qemu基本架构

最近在阅读qemu底层源码,由于网上资料甚少,从基本架构开始了解会好很多。

(于博客中整理搬运供自己学习)

如图所示,QEMU由以下几个部分组成:

l  Hypervisor控制仿真

l  Tiny Code Generator(TCG)在虚拟机器代码和宿主机代码之间进行转换。

l  软件内存管理单元(MMU)处理内存访问。

l  磁盘子系统处理不同的磁盘映像格式

l  设备子系统处理网卡和其他硬件设备

下面将对这些组件介绍。

Hypervisor管理程序

Hypervisor(虚拟机管理程序)是一种创建和运行虚拟机的虚拟机监视器。 QEMU中的Hypervisor(虚拟机管理程序)从磁盘映像加载二进制机器代码,使用TCG将其转换为本机机器代码,连接到虚拟或实际设备,并启动软件MMU,然后开始在磁盘映像中模拟操作系统。其中,TCG和软件MMU是实现虚拟化CPU和内存的关键。

而集成KVM后,QEMU将使用Linux内核的KVM功能以纯模式执行虚拟机。KVM基本上是Linux内核中的Hypervisor(虚拟机管理程序)。它可以并行运行多个操作系统。QEMU可以在KVM中启动一个新线程以执行模拟操作系统,然后KVM控制执行。从这部分来说,KVM的Hypervisor(虚拟机管理程序)替换掉了QEMU的Hypervisor(虚拟机管理程序)。

微代码生成器(TCG)

在QEMU中,Tiny Code Generator(TCG)将源处理器机器代码转换为虚拟机运行所需的机器代码块(如x86机器代码块)。从物理硬件的架构和角度上来说,不可能在一个处理器上运行为另一个处理器的指令集架构(ISA)编译的机器代码,例如,x86处理器上的ARM机器代码。因此,引入中间环节对不同的处理器指令集架构(ISA)进行翻译和转换是实现虚拟化通用性的技术途径和解决方案。在Tiny Code Generator(TCG)中,这些已经翻译的代码块放在转换缓存中,并通过跳转指令将源处理器的指令集(ISA)和目标处理器的指令集(ISA)链接在一起。当Hypervisor(虚拟机管理程序)在执行代码时,存放于转换缓存中的链接指令可以跳转到指定的代码块,并且执行可以在不同的已翻译代码块上运行,直到需要翻译新块为止。在执行的过程中,如果遇到了需要翻译的代码块,执行动作就会暂停并回会跳回到Hypervisor(虚拟机管理程序),Hypervisor(虚拟机管理程序)就会使用和协调TCG对需要进行二进制翻译的源处理器指令集(ISA)进行转换和翻译并存储到转换缓存中。

下图显示了QEMU的TCG工作原理:

image.png

图.微代码生成器工作原理

在TCG在运行的过程中存在一个小缺点,即它无法正确运行自修改代码,因为它没有将修改后的代码页进行标记,再次运行时需要重新翻译。这影响了QEMU的二进制运行效率,从另外一个角度来说,这也增加了一定的安全性。自修改代码在软件世界中容易被漏洞利用。特别是缓冲区溢出攻&击等内存损坏漏洞,这些漏洞利用威胁代理(例如后门)提供的特殊代码覆盖易受攻&击的应用程序代码,如果已经被覆盖的代码已经被运行(并因此被缓存),出了正常运行的会导致漏洞攻&击利用外,更多的时候则会导致TCG运行和翻译失败,从而导致程序复现异常或崩溃。

此外,在翻译的过程中,如果新处理器使用的寄存器多于x86处理器并且具有许多复杂指令,那么对TCG进行编程以处理和适应新的CPU仿真就可能需要大量的工作。目前来说,QEMU所支持的大部分处理器都拥有部分相同的指令集。例如,“MOV”指令几乎存在于所有处理器中,并且可以简单地复制,除非CPU寄存器中存在一些位大小差异。例如,在32位处理器上模拟64位处理器可能需要许多额外的指令,这也需要更多时间在TCG转换器中进行编程。

在QEMU的源代码中,有一个名为'tcg'的子目录,其中包含将机器指令转换为相应的x86机器指令的代码。此代码是一个用C编写的简单翻译状态机。还有用于内存访问和跳转的特殊转换,因为它们可以生成对软件内存管理单元的调用。而虚拟化CPU和内存也往往是在一起的,因为从本质上来说,CPU的工作就是对内存的区域数据进行搬运,CPU是内存的搬运工。在QEMU保护代码块之外的其他内存区域。机器代码中的跳转和分支也必须到达正确的存储器地址。

所以通过二进制翻译技术,针对CPU的仿真和虚拟化就非常简单了。TCG和Hypervisor(虚拟机管理程序)能够实现基于CPU的仿真,其中,其CPU仿真流程如下图所示:

image.png

从上图我们可以看到,针对CPU的仿真和虚拟化其实就是将源处理器的指令集(ISA)转换和翻译成目标处理器的指令集(ISA)。CPU仿真和虚拟化就是通过中间的转换和翻译来实现的,由此,针对CPU的虚拟化的第一种技术就完全实现了。这种二进制翻译技术是最早的CPU虚拟化技术,诞生了VMware这样的虚拟化巨头,也诞生了QEMU这样的开源虚拟化鼻祖。

 

硬件设备

虚拟机的硬件设备要求可以通过直接连接主机中的实际物理设备或通过QEMU中的硬件设备仿真来实现。与硬件相关的大多数QEMU代码位于目录“hw”中。

在QEMU中,存在两种使用硬件设备的方式:直通模式使用主机实际物理设备和QEMU的设备驱动仿真实现的模拟虚拟设备。如果采用直通方式使用实际的物理设备,那么就会抢占主机的设备使用权,并且其他虚拟机也将无法使用该物理设备。在直通模式中,虚拟机可以直接访问USB总线或PCI总线,并可以直接与设备通信。一般情况下,采用直通模式的物理设备都是很难进行QEMU仿真的设备,比如网络摄像头、串行和并行端口等。其他设备因为大部分虚拟机都会使用,而且很难与主机共享,例如网络设备,因此大都会使用QEMU模拟仿真的虚拟设备。比如在虚拟机的网络设备中,可通过模拟网卡来解决,从而在网络堆栈上添加额外的层。此外,QEMU可以选择连接到Linux内核中的“virtio”半虚拟化驱动程序,这意味着Linux内核处理虚拟机和硬件设备之间的输入/输出,而不采用QEMU的模拟设备进行中转和传输(仅用作中介)。

 

磁盘映像

QEMU可以处理几种不同的磁盘映像格式。首选格式为raw或qcow2。Raw是一种非常简单的格式,它将文件系统中的字节逐字节存储在文件中。大多数其他仿真器都支持此格式。Qcow2是QEMU自己的图像格式,对小图像很有用。并且支持磁盘映像压缩以及捕获磁盘映像状态的快照。还支持另外两种格式:在VirtualBox中使用的vdi和在VMWare中使用的vmdk。

QEMU的磁盘映像通过其存储IO协议栈来进行支持,其存储协议栈如下图所示:

image.png

image.png

图 QEMU存储协议栈

从QEMU的存储协议栈来说,应用程序和虚拟机内核的工作类似于裸机。虚拟机通过仿真硬件与QEMU交互,并将IO执行情况的控制流和数据流交互给QEMU,QEMU代表虚拟机对磁盘镜像文件执行I / O操作。而从主机内核层面上,主机内核会将虚拟机I / O视为一种用户空间的应用程序IO请求进行正常的执行处理。

软件MMU

传统处理器中的内存管理单元(MMU)处理对计算机内存位置的访问。当处理器想要访问某个存储器地址时,MMU获取该地址的内容。此内容可以来自处理器芯片上的本地快速缓存,来自随机存取存储器(RAM)或来自光盘。它甚至可以做出一些关于缓存某些内存位置的控制决定。

QEMU有一个基于软件的MMU,其工作方式与硬件MMU类似。它使用地址转换缓存,其中包含访客地址、主机地址和偏移值,以提高转换速度。它还允许智能链接代码块,以便在没有内存故障的情况下实现更快的执行,其中必须重新加载和重新转换内存块。

在寻找在QEMU中运行的虚拟机的漏洞时,软件MMU是否正在进行翻译和正确放置块会是其测试和Fuzz的重点。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值