热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Qemu源码分析

参考:http:lists.gnu.orgarchivehtmlqemu-devel2011-04pdfhC5rVdz7U8.pdftb_find_fast:查找下一个TB(T

参考: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函数中


id="codeSnippetWrapper">
id="codeSnippet">

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。


id="codeSnippetWrapper">
id="codeSnippet">

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。


id="codeSnippetWrapper">
id="codeSnippet">

cpu_tb_exec

|

tcg_qemu_tb_exec


id="codeSnippetWrapper">
id="codeSnippet">

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


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


id="codeSnippetWrapper">
id="codeSnippet">

objdump -d vl.o



id="codeSnippetWrapper">
id="codeSnippet">

00000000000000ea :

ea: 55 push
%rbp

eb: 48 89 e5 mov
%rsp,%rbp

ee: 48 83 ec 20 sub
$0x20,%rsp

f2: 89 7d ec mov %edi,-0x14(%rbp)

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

fc: 00 00

fe: 48 89 45 f8 mov %rax,-0x8(%rbp)

102: 31 c0 xor %eax,%eax

104: 8b 45 ec mov -0x14(%rbp),%eax

107: 48 98 cltq

109: 48 83 c0 3f add $0x3f,%rax

10d: 48 c1 e8 06 shr $0x6,%rax

111: c1 e0 03 shl $0x3,%eax

114: 89 45 f4 mov %eax,-0xc(%rbp)

117: 8b 45 f4 mov -0xc(%rbp),%eax

11a: 48 98 cltq

11c: 48 89 c7 mov %rax,%rdi

11f: e8 00 00 00 00 callq 124

124: 48 8b 55 f8 mov -0x8(%rbp),%rdx

128: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx

12f: 00 00

131: 74 05 je 138

133: e8 00 00 00 00 callq 138

138: c9 leaveq

139: c3 retq


  

 

000000000000013a :
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
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

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

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
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
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
1c3: e8 00 00
00 00 callq 1c8
1c8: 48 83 c4
28 add $0x28,%rsp
1cc: 5b pop
%rbx
1cd: 5d pop %rbp
1ce:
c3 retq

 


 

Qemu源码分析,布布扣,bubuko.com


推荐阅读
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文详细介绍了Git分布式版本控制系统中远程仓库的概念和操作方法。通过具体案例,帮助读者更好地理解和掌握如何高效管理代码库。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 优化局域网SSH连接延迟问题的解决方案
    本文介绍了解决局域网内SSH连接到服务器时出现长时间等待问题的方法。通过调整配置和优化网络设置,可以显著缩短SSH连接的时间。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 本文介绍如何使用Python进行文本处理,包括分词和生成词云图。通过整合多个文本文件、去除停用词并生成词云图,展示文本数据的可视化分析方法。 ... [详细]
  • 本文介绍如何通过SSH协议使用Xshell远程连接到Ubuntu系统。为了实现这一目标,需要确保Ubuntu系统已安装并配置好SSH服务器,并保证网络连通性。 ... [详细]
  • 落樱3D v0.5是一款在Android平台上发布的3D美少女格斗游戏,本次更新带来了多项新功能和优化。 ... [详细]
  • TechStride 网站
    TechStride 成立于2014年初,致力于互联网前沿技术、产品创意及创业内容的聚合、搜索、学习与展示。我们旨在为互联网从业者提供更高效的新技术搜索、学习、分享和产品推广平台。 ... [详细]
  • 本文将带领读者深入了解Android系统源码在手机中的实际表现,通过详细的步骤和专业的解释,帮助你更好地理解Android系统的底层运作机制。 ... [详细]
  • 本文介绍了如何使用Java中的同步方法和同步代码块来实现两个线程的交替打印。一个线程负责打印1到52的数字,另一个线程负责打印A到Z的字母,确保输出顺序为12A34B...5152Z。 ... [详细]
  • 通过Web界面管理Linux日志的解决方案
    本指南介绍了一种利用rsyslog、MariaDB和LogAnalyzer搭建集中式日志管理平台的方法,使用户可以通过Web界面查看和分析Linux系统的日志记录。此方案不仅适用于服务器环境,还提供了详细的步骤来确保系统的稳定性和安全性。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
author-avatar
2分之11989_330
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有