QEMU架构浅析

1、QEMU简介及与KVM等虚拟化的关系

QEMU是“Quick Emulator”的缩写,是一个用C语言编写的开源虚拟化软件。本文的目的是描述本人所理解的QEMU技术架构的看法,并以此抛砖引玉。众所周知,QEMU的源代码开发文档很是稀少,描述内部结构和工做机理的文档更是百里挑一,通常的开发人员想要从事QEMU的开发工做,一般只能从源代码入手。所以,对于技术人员来讲,了解QEMU是一项艰巨的任务。编程

QEMU有几种虚拟化模式。首先,它可使用基于内核的虚拟机(KVM)执行x86处理器硬件虚拟化,以几乎比拟硬件本机的速度执行运算任务。其次,它能够经过机器代码的实时转换来模拟其余处理器以用于虚拟机运行不一样平台的操做系统。最后,它可使用实时转换为其余架构运行简单的程序,相似于Linux中的Wine。由于QEMU没有图形用户界面(GUI),而其提供的核心能力又是关键而重要的,所以一般用做更复杂的虚拟化管理器的一部分。好比,咱们常用的开源VirtualBoxXen等虚拟化产品,其核心底层的虚拟化部分就有集成和使用QEMU,此外,主流的KVM虚拟化也是集成和使用QEMU的主力虚拟化管理器系统。缓存

KVM的角度来讲,KVMKernel Virtual Machine)是Linux的一个内核驱动模块,它可以让Linux主机成为一个Hypervisor(虚拟机监控器)。在支持VMXVirtual Machine Extension)功能的x86处理器中,Linux在原有的用户模式和内核模式中新增长了客户模式,而且客户模式也拥有本身的内核模式和用户模式,虚拟机就是运行在客户模式中。KVM模块的职责就是打开并初始化VMX功能,提供相应的接口以支持虚拟机的运行。KVM经过调用Linux自己内核功能,实现对CPU的底层虚拟化和内存的虚拟化,使Linux内核成为虚拟化层。KVM20072月被导入Linux 2.6.20内核中。从存在形式来看,它包括两个内核模块:kvm.kokvm_intel.ko(或kvm_amd.ko),本质上,KVM是管理虚拟硬件设备的驱动,该驱动使用字符设备/dev/kvm(由KVM自己建立)做为管理接口,主要负责vCPU的建立、虚拟内存的分配、vCPU寄存器的读写以及vCPU的运行。安全

QEMU的角度来讲,QEMUQuick Emulator)自己并不包含或依赖KVM模块,而是一套由Fabrice Bellard编写的模拟计算机的自由软件。QEMU虚拟机是一个纯软件的实现,能够在没有KVM模块的状况下独立运行,可是性能比较低。QEMU有整套的虚拟机实现,包括处理器虚拟化、内存虚拟化以及I/O设备的虚拟化。在不须要KVM加速的状况下,QEMU经过一个特殊的“重编译器”对特定的处理器的二进制代码进行翻译,从而具备了跨平台的通用性。QEMU有两种工做模式:系统模式,能够模拟出整个电脑系统,另外一种是用户模式,能够运行不一样与当前硬件平台的其余平台上的程序(好比在x86平台上运行跑在ARM平台上的程序)。目前最新版本是4.x。从QEMU角度来看,虚拟机运行期间,QEMU经过KVM模块提供的系统调用接口进行内核设置,由KVM模块负责将虚拟机置于处理器的VMX模式运行。QEMU使用了KVM模块的虚拟化功能,为本身的虚拟机提供硬件虚拟化加速以提升虚拟机的性能。网络

而如今流行的KVM虚拟化平台,就是在修改了QEMU代码,把他模拟CPU、内存的代码换成KVM,而网卡、显示器等留着,所以QEMU+KVM就成了一个完整的虚拟化平台。因为KVM运行在内核空间,只是内核模块,QEMU运行在用户空间,实际模拟建立,管理各类虚拟硬件(磁盘,网卡,显卡等)。从KVM的角度来讲,用户无法直接跟内核模块交互,须要借助用户空间的管理工具,所以须要借助QEMU这个运行在用户空间的工具。KVMQEMU相辅相成,QEMU经过KVM达到了硬件虚拟化的速度,而KVM则经过QEMU来模拟设备并实现和内核空间的KVM的交互,虽然这个交互并不只仅只有QEMU可以办到。此外,因为QEMU模拟IO设备效率不高的缘由,如今经常采用半虚拟化的virtio方式来虚拟IO设备。架构

综上,理解了QEMUKVM的关系,也就理解了VirtualBoxXen等虚拟化产品集成和使用QEMU的关系了。ide

2、QEMU架构及组成

QEMU的架构以下图所示,由几个基本的组件组成:工具

image.png

QEMU架构图性能

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

l  Hypervisor控制仿真ui

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

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

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

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

下面将对这些组件介绍。

2.1 Hypervisor管理程序

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

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

3.2微代码生成器(TCG

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

下图显示了QEMUTCG工做原理:

image.png

.微代码生成器工做原理

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

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

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

因此经过二进制翻译技术,针对CPU的仿真和虚拟化就很是简单了。TCGHypervisor(虚拟机管理程序)可以实现基于CPU的仿真,其中,其CPU仿真流程以下图所示:

image.png

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

 

2.3硬件设备

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

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

 

2.4磁盘映像

QEMU能够处理几种不一样的磁盘映像格式。首选格式为rawqcow2Raw是一种很是简单的格式,它将文件系统中的字节逐字节存储在文件中。大多数其余仿真器都支持此格式。Qcow2QEMU本身的图像格式,对小图像颇有用。而且支持磁盘映像压缩以及捕获磁盘映像状态的快照。还支持另外两种格式:在VirtualBox中使用的vdi和在VMWare中使用的vmdk

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

image.png

image.png

QEMU存储协议栈

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

2.5软件MMU

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

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

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

3、总结

其实搞清楚QEMU的技术架构和实现细节,咱们须要弄明白QEMU的架构和组成,以及每一个组件的做用及运行机制。此外,咱们还须要了解每一个组成组件之间的相互交互关系,从数据流的角度来看,其主要是控制流和数据流;从IO角度来看,其主要是网络IO和存储IO,从技术实现机制来看,其主要是虚拟化CPU和内存以及存储、网络协议栈的实现。本文有许多的未尽事宜,待请后续补充。

相关文章
相关标签/搜索