参考:http://lists.gnu.org/archive/html/qemu-devel/2011-04/pdfhC5rVdz7U8.pdf

1. qemu与Bochs的区别:

1. Bochs

Bochs和qemu都是以软件仿真为主的虚拟软件,二者的区别何在?

Bochs完全是以软件的方式对目标程序(OS以及运行在其上的应用程序)进行仿真。Bochs在自己的内部维护着CPU、内存、IO设备的数据结构,每当Bochs仿真一条指令,就会按照这条指令在真实硬件上运行时应当产生的效果,对这些软件维护硬件数据结构产生相应的影响。

这种逐条处理的方式,可以保持与真实运行时完全相同的粒度,便于学习和调试。但是由于这是一种一对多的映射方式,即一条机制指令,会被解释成N条指令执行,因此效率的下降是在所难免。

2. qemu

qemu采取的是另外一种粒度的仿真。

qemu会从目标程序中,截取当前需要运行的一段代码(被称作Translation Block),将这段代码先翻译成中间语言(Intermediate Code),再将中间语言翻译成主机体系相关的二进制代码。

由于Translation Block的粒度大于单条机制指令的粒度,qemu相当于是batch处理指令的仿真操作的,因此会比逐条处理的Bochs性能上快一些。

除此之外,qemu还会优化对于Translation Block的缓存,以及将多个连接执行的Translation Block链接起来在同一批次进行处理;这两种方式对于反复执行的代码段的仿真性能有很大的提升。

3. 总结

简而言之,Bochs适合用于学习,以及比较简单的任务处理,Bochs自带的调试器也很给力,用Bochs调试Linux内核是不错的选择(可以参考:http://www.cnblogs.com/long123king/p/3559816.html等等),但是Bochs不适合用于真实地仿真大型的操作系统,比如Windows,基本上无法做到。

qemu由于处理方式上有优化,不像Bochs那样可以“原汁原味”地展现指令级别的执行过程,因此不太适合于学习;但是由于qemu性能上的提升,还可以配合内核虚拟化模块kvm,甚至xen,因此qemu可以像主流的虚拟桌面软件(VirtualBox, Vmware等等)一样流畅地运行多种操作系统。如果你需要在Linux上面虚拟化Windows,肯定是qemu更加适合一些。

tb_find_fast: 查找下一个TB(Translation Block),并且生成主机代码;

tcg_qemu_tb_exec:执行生成的主机代码,主机代码由三部分组成:

2. qemu的处理流程

qemu的仿真主循环位于cpu-exec.c:cpu_exec函数中

for(;;)

{

......

tb = tb_find_fast(env);

......

next_tb = cpu_tb_exec(cpu, tc_ptr);

......

}

1. tb_find_fast:

用来准备Translation Block;如果缓存中已经准备好的Translation Block,就直接返回;否则调用tb_find_slow函数来构造一个新的TB。

tb_find_fast

    |

tb_find_slow

    |

tb_gen_code

    |

cpu_gen_code

    |

gen_intermediate_code 【Guest Code --> tcg op(中间代码)】

    |

tcg_gen_code【tcg op(中间代码) --> Host Code】

 

其中,gen_intermediate_code是与体系相关的函数实现,x86的实现位于target-i386/translate.c中,内部调用disas_insn逐条指令处理。

而tcg_gen_code会调用tcg_gen_code_common,从TB中取出中间代码,将其转换成主机代码。

2. cpu_tb_exec:

用来执行生成好的TB。

cpu_tb_exec

    |

tcg_qemu_tb_exec

#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)

prologue和epilogue是compiler在生成目标代码时,对函数栈帧的保存与恢复的代码,我们信手拈来一个例子

objdump -d vl.o

下面代码中红色的部分就分别是函数的prologue和epilogue。

000000000000013a <bitmap_empty>:

     13a:       55                      push   %rbp

     13b:       48 89 e5                mov    %rsp,%rbp

     13e:       53                      push   %rbx

     13f:       48 83 ec 28             sub    $0x28,%rsp

     143:       48 89 7d d8             mov    %rdi,-0x28(%rbp)

     147:       89 75 d4                mov    %esi,-0x2c(%rbp)

     14a:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax

     151:       00 00 

     153:       48 89 45 e8             mov    %rax,-0x18(%rbp)

     157:       31 c0                   xor    %eax,%eax

     159:       8b 45 d4                mov    -0x2c(%rbp),%eax

     15c:       83 f8 40                cmp    $0x40,%eax

     15f:       77 42                   ja     1a3 <bitmap_empty+0x69>

     161:       48 8b 45 d8             mov    -0x28(%rbp),%rax

     165:       48 8b 10                mov    (%rax),%rdx

     168:       8b 45 d4                mov    -0x2c(%rbp),%eax

     16b:       48 98                   cltq   

     16d:       83 e0 3f                and    $0x3f,%eax

     170:       48 85 c0                test   %rax,%rax

     173:       74 19                   je     18e <bitmap_empty+0x54>

     175:       8b 45 d4                mov    -0x2c(%rbp),%eax

     178:       83 e0 3f                and    $0x3f,%eax

     17b:       be 01 00 00 00          mov    $0x1,%esi

     180:       89 c1                   mov    %eax,%ecx

     182:       48 d3 e6                shl    %cl,%rsi

     185:       48 89 f0                mov    %rsi,%rax

     188:       48 83 e8 01             sub    $0x1,%rax

     18c:       eb 07                   jmp    195 <bitmap_empty+0x5b>

     18e:       48 c7 c0 ff ff ff ff    mov    $0xffffffffffffffff,%rax

     195:       48 21 d0                and    %rdx,%rax

     198:       48 85 c0                test   %rax,%rax

     19b:       0f 94 c0                sete   %al

     19e:       0f b6 c0                movzbl %al,%eax

     1a1:       eb 11                   jmp    1b4 <bitmap_empty+0x7a>

     1a3:       8b 55 d4                mov    -0x2c(%rbp),%edx

     1a6:       48 8b 45 d8             mov    -0x28(%rbp),%rax

     1aa:       89 d6                   mov    %edx,%esi

     1ac:       48 89 c7                mov    %rax,%rdi

     1af:       e8 00 00 00 00          callq  1b4 <bitmap_empty+0x7a>

     1b4:       48 8b 5d e8             mov    -0x18(%rbp),%rbx

     1b8:       64 48 33 1c 25 28 00    xor    %fs:0x28,%rbx

     1bf:       00 00 

     1c1:       74 05                   je     1c8 <bitmap_empty+0x8e>

     1c3:       e8 00 00 00 00          callq  1c8 <bitmap_empty+0x8e>

     1c8:       48 83 c4 28             add    $0x28,%rsp

     1cc:       5b                      pop    %rbx

     1cd:       5d                      pop    %rbp

     1ce:       c3                      retq  

qemu的执行流程中,本来属于qemu的代码,我们可以称之为static code;而通过TB生成的主机代码,我们可以称之为dynamic code,因此必定要有一个入口点,让static code将dynamic code调用起来。qemu采用的是类似函数prologue的方式,这也是为什么我们会看到code_gen_prologue的原因。

code_gen_prologure指向的是TB中动态生成的相对于整个TB的prologue。

 

qemu源码分析的更多相关文章

  1. [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)

    对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...

  2. 鸿蒙轻内核源码分析:文件系统FatFS

    摘要:本文为大家介绍FatFS文件系统结构体的结构体和全局变量,并分析FatFS文件操作接口. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列二一 03 文件系统FatFS>,作者:zh ...

  3. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  4. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  5. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  6. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  7. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  8. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  9. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

随机推荐

  1. gokit 统计分析 M2M接入服务 OTA固件升级 硬件社交化

    统计分析 M2M接入服务  OTA固件升级 硬件社交化 统计分析 为智能硬件定制的统计分析服务.只需添加入一行代码的集成工作,多维度的设备使用和用户行为数据就能自动统计出来. 演示 特色一:设备上线情 ...

  2. cs224d 作业 problem set2 (二) TensorFlow 实现命名实体识别

    神经网络在命名实体识别中的应用 所有的这些包括之前的两篇都可以通过tensorflow 模型的托管部署到 google cloud 上面,发布成restful接口,从而与任何的ERP,CRM系统集成. ...

  3. VEX IR语言语法

    /*---------------------------------------------------------------*//*--- High-level IR description - ...

  4. 33-python基础-python3-列表插入元素-insert()方法-append()方法-extend()方法

    1-insert()方法 insert()方法可以在列表任意下标处插入一个值. insert()方法的第一个参数是新值的下标,第二个参数是要插入的新值. 2-append()方法 调用 append( ...

  5. CSS 中功能相似伪类间的区别

    导读: CSS3 中有许多伪类选择器,其中一些伪类选择器的作用近似却又不完全一样,下面我们就来看一看到底有什么不一样. 1.:only-child 与 :only-of-type 测试的代码: < ...

  6. zabbix--External checks 外部命令检测

    概述zabbix server 运行脚本或者二进制文件来执行外部检测,外部检测不需要在被监控端运行任何 agentditem key 语法如下: 参数 定义 script shell 脚本或者二进制文 ...

  7. Neo4j parameter

    Neo4j browser: $ :help param Set a parameter Set a parameter to be sent with queries. The :param nam ...

  8. SpringBoot 应用程序启动过程探秘

    概述 说到接触 SpringBoot 伊始,给我第一映像最深的是有两个关键元素: 对照上面的典型代码,这个两个元素分别是: @SpringBootApplication SpringApplicati ...

  9. Spring项目下js文件无法引用

    问题:最近练习spring-mvc框架的时候,引用了jQuery,但是运行的时候,jQuery做的事情都没有响应,代码也没有任何报错,在网上找了一下,发现是由于spring配制的是/,所有的资源都被屏 ...

  10. 将arcEngine9.3和dev9.2.4开发的项目升级成arcObject10.2和dev15.1.3过程中遇到的问题和解决

    好久没碰.net了,arcgis更是感觉都忘干净了,今天将arcEngine9.3和dev9.2.4开发的一个项目升级成arcObject10.2和dev15.1.3过程中遇到了一系问题,留个笔记,留 ...