qemu源码分析
参考: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源码分析的更多相关文章
- [dpdk] 熟悉SDK与初步使用 (三)(IP Fragmentation源码分析)
对例子IP Fragmentation的熟悉,使用,以及源码分析. 功能: 该例子的功能有二: 一: 将IP分片? 二: 根据路由表,做包转发. 路由表如下: IP_FRAG: Socket : ad ...
- 鸿蒙轻内核源码分析:文件系统FatFS
摘要:本文为大家介绍FatFS文件系统结构体的结构体和全局变量,并分析FatFS文件操作接口. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列二一 03 文件系统FatFS>,作者:zh ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
随机推荐
- visual studio code -- python
录: 前提: 已安装python 在vsc中安装pthon模块 快速入门 打开控制台(ctrl+shift+P):Python: Select Interpreter,选择python解释器 或者在软 ...
- Excel2016怎么批量删除空白行 如何删除空白行
我们在编辑Excel文档的时候,如果表格中有大量的空白行,这时我们怎么样把它们批量删除呢?下面我们就一起来看看操作的方法吧. 工具/原料 Excel2016 方法/步骤 首先在电脑上打 ...
- vue入门例子
vue入门例子 1.声明示渲染 {{message}} 2.绑定事件 v-bind 3.控制切换一个程序是否显示 v-if 4.渲染循环 ...
- 单机zookeeper部署伪集群
1.zookeeper介绍 ZooKeeper 是一个为分布式应用所设计的分布的.开源的协调服务.分布式的应用可以建立在同步.配置管理.分组和命名等服务的更高级别的实现的基础之上. ZooKeeper ...
- testNG官方文档翻译-5 测试方法,测试类和测试组
5.1 - 测试方法 测试方法是被 @Test注解的方法.这些方法的返回值会被忽略,除非在testng.xml中将allow-return-values设置为true. <suite allow ...
- python调用tushare获取沪深股通十大成交股
接口:hsgt_top10 描述:获取沪股通.深股通每日前十大成交详细数据 注:tushare库下载和初始化教程,请查阅我之前的文章 输入参数 名称 | 类型 | ...
- Linux下JDK1.6升级1.8版本
先不管是否已安装JDK1.6还是JDK1.7,先下载 jdk-8u45-linux-x64.rpm 然后上传到 /usr/local/src 去.当然其他目录也可以.这里是默认位置 给所有用户 ...
- 19-python基础-进制之间的转换
二进制-八进制-十进制-十六进制相互转换 1.十进制转为其他进制 # (1)十进制转二进制 a = 8 bin(a) --->>'0b1000' # (2)十进制转八进制 oct(a) - ...
- linux 下安装chrome的rpm包
1. 下载chrome的rpm包,假设叫cho. 2.执行命令 rpm -ivh cho 3.报错提示需要lsb>=4.0,执行命令 yum install lsb 等待安装完毕. 4. 重新执 ...
- zabbix--Simple checks 基本检测
开始 Simple checks 通常用来检查远程未安装代理或者客户端的服务. 使用 simple checks,被监控客户端无需安装 zabbixagent 客户端, zabbix ser ...