<--- 以下是2007年做相关工作的学习笔记(留意,版本比较早了,其后可能有各种改动)。多年过去了,世事变迁,加上我的水平非常有限,现在翻出来仅供批评,勿认真,而且现在我自己也看不懂了。
--->
QEMU是一款虚拟机软件,模拟了包括CPU在内的各种硬件系统,包括:
QEMU虚拟机的初始化过程:
以下分若干小节介绍具体工作流程。
指令的翻译和执行过程
Guest即被虚拟的系统,Guest的指令系统不一定跟Host机相同,比如可以在x86上虚拟出一台arm机器来。
对guest指令的翻译和执行过程如下:
指令翻译过程的传送图
Guest和host的寻址转换关系
TB相关数据结构
![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
QEMU是一款虚拟机软件,模拟了包括CPU在内的各种硬件系统,包括:
- 指令解释和执行
- 异常、中断、时钟等CPU相关模块
- 内存、网卡、硬盘,显示系统,以及键盘和鼠标输入
QEMU虚拟机的初始化过程:
- 分配、初始化虚拟的CPU、内存等数据结构。
- 分配、初始化其他硬件设备
- 如指定了CPU状态和内存镜像则将两者加载
- 启动时钟系统
- 调用cpu_exec运行guest系统
以下分若干小节介绍具体工作流程。
指令的翻译和执行过程
Guest即被虚拟的系统,Guest的指令系统不一定跟Host机相同,比如可以在x86上虚拟出一台arm机器来。
对guest指令的翻译和执行过程如下:
- 根据guest的CPU状态得到当前指令指针的guest逻辑地址;
- 根据mmu状态得到在guest物理地址;
- 加上guest内存在host内存的基址得到待执行指令的host逻辑地址;
- 取出待执行指令,在微操作函数库中查找待执行指令的微操作函数(一小段C代码,但是已经编译为二进制)并拷贝到执行缓冲区TB;
- 根据指令执行流程,对下一条指令重复上面步骤,直到发现一条jump指令,或者一条修改CPU状态并无法预测结果的指令,或者发现TB满了;
- 给执行缓冲区TB生成一段段落结束代码,其中包含jump的跳向;
- 调用dyngen函数对上述生成的代码做重定位,使其能寻址到guest数据区;
- 执行上述生成的代码;
指令翻译过程的传送图
- Op.c文件编译为obj格式的微操作函数库。
- 每条guest指令对应一个微操作序列。
- 拷贝guest指令对应的微操作序列到TB中,形成host指令序列。
Guest和host的寻址转换关系
- Disas_insn(): 对guest代码逐条翻译,并存放在TB中。
- Dyngen_code(): 重定向翻译后的代码。
TB相关数据结构
- TB是一个数组:TranslationBlock tbs[CODE_GEN_MAX_BLOCK