研究生入学的时候,看了一篇论文——《Xen and the art of virtualization》。现在时隔一年,准备对此进行一番整理。下文是我Xen为例的半虚拟化技术的理解:
首先从虚拟机说起,虚拟机技术最早由IBM于上世纪六七十年代提出,被定义为硬件设备的软件模拟实现。在那个年代,计算机的硬件成本相当大,为了能够提高计算机的利用率,于是提出了这样一种技术:将一台机器通过软件虚拟成多台机器从而为不同的应用提供服务。如今虚拟机技术应用广泛,可租用的服务器都是使用了不同方案的虚拟化技术。
我们通常提到的虚拟机都是系统虚拟机,如IBM VM/370、VMware ESX Server、Xen。系统虚拟机在二进制指令集系统结构(ISA)的层次上提供一个完整的系统级环境。因此,用户会觉得自己在使用整个计算机。一台运行多个虚拟机的计算机可以支持多个不同的操作系统。在一个传统的平台上,一个单独的操作系统拥有所有的硬件资源,但是通过使用虚拟机,多个操作系统共享硬件资源。
下图是典型的虚拟机层次结构。它比传统的平台多了一个虚拟机监视器(Virtual Machine Monitor),虚拟机监视器VMM处于硬件和虚拟机层之间。虚拟机监视器VMM负责Host和Guest之间的通信。在虚拟机系统中,对于上层应用,虚拟机就是真实的计算机。
虚拟化技术可以分为完全虚拟化、半虚拟化。
起初是为了解决x86体系结构上完全虚拟化的困难,它需要修改OS,工作效率相对完全虚拟化要高很多。典型的有Xen、KVM-PowerPC。
x86体系是导致半虚拟化技术产生的重要原因。因为x86指令系统中存在部分敏感指令不是特权指令。什么意思呢?下面来从特权指令和敏感指令的角度进行解释:
特权指令是一些操作和管理关键系统资源的指令,这些指令只有在最高特权级上才能够运行。如果在非最高特权级上运行,特权指令会引发一个异常,处理器会陷入到最高特权级,然后由系统软件处理。但是并不是所有的特权指令都会引发异常(x86指令系统中的特权指令会有这种问题),最关键的是这些特权指令在不同的特权级上运行的结果会不一样,甚至可能会被直接忽略。
传统的机器只有特权指令和普通指令两种概念,而在有虚拟化的机器上则还有一个独特的概念:敏感指令。敏感指令是指在虚拟化时必须要在最高特权级运行的指令。在RISC体系中,所有的特权指令都是敏感指令,因此可以支持完全虚拟化。但是在x86体系的虚拟化中,部分敏感指令并不是特权指令,那么这些非特权指令的敏感指令在系统运行过程中就不会引发异常,也就无法被捕获并在最高特权级执行。而这些敏感指令在非最高特权级下运行和在最高特权级下运行会有不同的结果,这对于一个要求性能可靠的计算机不能绝对容忍的。因此,半虚拟化技术,以Xen为先例,主要解决的就是这个问题——如何捕获非特权指令的敏感指令。
上面多次提到了特权级等概念,下面来进行简要的解释。
在操作系统中,我们经常看到用户态、内核态这些概念,而事实上这两个态的实现就是通过特权级来实现的。如下图所示,现在大部分的计算机体系结构都有两个或两个以上的特权级别,用来分隔内核和应用软件。以x86为例,它拥有4个特权级别(0 to 3),一般用ring来表示。Ring后面的数字越小特权级别越小。在未虚拟化的机器上,Ring0运行操作系统,Ring1、Ring2支持设备驱动,Ring3跑应用程序。而现在的x86处理器中,64位架构已经非常普遍,64位CPU因为必须支持页表模式,所以只需要两个特权级别:ring0、ring3。
Xen的整体框架如下图所示。它分为三层,从底层到上层依次是物理层、VMM、Domain。VMM层也就是Xen Hypervisor,负责为上层操作系统提供虚拟化的硬件资源,负责管理和分配这些资源,并确保上层虚拟机(也称为虚拟域Domain)之间的相互隔离。Xen采用混合模式,因而设定了一个特权域用以辅助Xen管理其他的域,并提供虚拟资源服务,该特权域称为Domain0,而其余的域则称为DomainU。
下面按层次来介绍Xen的结构。底层硬件不进行过多赘述。
控制接口也称为特权控制接口,仅能被Dom0使用,用于帮助Domain0控制管理其他Domain。控制接口提供的具体功能包括Domain的创建。控制接口的具体功能包括Domain的创建、销毁、暂停、恢复及迁移,对其他Domain的CPU调度,内存分配以及设备访问等。
提供除虚拟CPU、MMU之外的所有硬件虚拟工作,包括DMA/IO、驱动程序、虚拟的PCI地址配置、虚拟硬件中断等。该接口只能被具有原生设备驱动的Domain使用,而对于其他Domain仅通过设备通道提供虚拟硬件服务。
Xen为每个Domain建立了VCPU结构,用以接收Guest OS中传递的指令,其中大部分的指令被VCPU直接提交到屋里CPU执行,而对于特权指令则需要经过确认之后交由Xen代为执行。
用于帮助Guest OS完成虚拟地址到物理地址的转换。Xen系统中增加了客户物理地址层,因而地址由原来的二层结构变为三层结构。Xen通过虚拟MMU仍能使用硬件MMU来完成地址转换。
是用于Domain和Xen之间、Domain相互之间的一种异步事件通知机制,用于处理Guest OS的虚拟中断、物理中断以及Domain之间的通信。事件通道是Xen系统的基本机制,与超级调用一起在Xen各个虚拟子系统中起到重要的作用。
在硬件虚拟化技术诞生之后,从Xen3.0开始就能够支持不修改内核的Guest OS。运行未修改内核的操作系统的Domain称为硬件虚拟机(HVM)。现在,运行在Xen上的虚拟域包括四种类型:特权域(Domain0)、独立设备驱动域(IDD)、硬件虚拟域、非特权域(DomainU)。
上述已经提到过了特权域,特权域Domain0在整个Xen系统中是独一无二的。Domain0随着Xen的启动而被创建,是第一个被创建的Domain。Domain0拥有原生设备驱动,具有直接访问硬件设备的特权,并通过和Xen提供的控制接口进行交互来控制和管理其他虚拟域。
运行在Dom0中的控制面板能够控制其它Domain的创建、销毁、配置和迁移;设备管理器则负责设备驱动的初始化和管理设备的访问,在访问设备过程中, 与直接模拟真实的物理设备不同,Xen向其他Domain提供的是抽象的设备,例如,其它Domain通过网卡的前端驱动所看到的网卡设备仅仅是一个通用 的网卡类设备,而非具体的某一个网卡,在接收到其它Domain通过网卡的前端驱动发送的I/O请求后,Dom0则利用网卡的后端驱动来确定具体的网卡, 并交由原生驱动完成I/O请求。
在最简单的Xen结构中,只存在一个特权域Dom0,这时Xen就好像一个硬件设备抽象层,将复杂的x86架构隐藏起来,所有的硬件设备被Dom0的 Guest OS控制,但这种结构存在很大的问题,若一个特殊设备驱动包含了一些漏洞,那它就有可能摧毁整个Dom0的内核,从而导致整个系统崩溃,为此,将设备驱动 由Dom0移入另一个虚拟域中,一方面可降低Dom0的运行负载,另一个方面杨也可减低系统的风险,一旦虚拟域由于使用设备驱动出面故障,Dom0就可以 很方便地重启该虚拟域,这些经过Dom0授权、能够使用特定设备驱动的虚拟域称为独立设备驱动域(Isolated Driver Domain,IDD)。可以避免由于DMA需求和I/O中断对Guest OS造成的影响。
Xen3.0支持运行未修改内核的Guest OS,但这需要使用特殊硬件技术的支技,例如Intel的VT-x或AMD的ADM-V技术。运行这些Guest OS的虚拟域称为硬件虚拟域;由于Guest OS没有修改内核,因此Guest OS不能直接支持Xen在半虚拟化下采用的分离设备驱动模型,这意味着Xen必须模拟出Guest OS能够支持的环境。若HVM中的Guest OS要使用Xen的半虚拟化技术,则必须先通过执行CPUID指令支访问一个特殊的虚拟寄存器和超级调用页面,然后同其他Domain中的Guest OS一样,通过修改超级调用页表来发布新的超级调用。
严格来讲,DomU是指除了Dom0之外的Domain,但由于IDD经过Dom0授权后能够使用设备驱动直接访问物理设备,因而IDD也属于“特权 域”,因此,DomU是除了Dom0和IDD之外的Domain,包括前面提到的HVM;相对Dom0 来说,DomU受到了许多限制,首当其冲的是对硬件访问,无论是HVM还是一般的DomU都不能直接访问物理设备,必须借助于Dom0或IDD才能完成。
设备管理器位于Domian0和IDD(Independent Device Domain)中,可作为系统BIOS的扩展,用于向所有的设备提供通用的管理接口,并负责在Domain启动时加载特定的设备驱动、建立管理设备通道、提供硬件配置接口并处理设备访问的错误。
控制面板是运行在Dom0中的一系列软件集合,用于同Xen中的控制接口交互,完成对整个Xen系统的管理工作,相当于系统的总控制台。它能够控制其他Domain的创建、销毁、配置和迁移。
原生设备驱动是指原来操作系统中所使用的普通设备驱动。在Xen系统中,只有经过授权的Domain才有权使用原生的设备驱动访问真实的硬件设备。通过支持原生设备驱动,Xen能够最大限度地利用操作系统中个设备驱动,减少Xen的开发难度,提高了效率,通过安全硬件接口,这些原生设备驱动能够限定在特定的I/O空间中,为Domain提供设备访问服务。
前端/后端设备驱动共同组成了Xen的分离设备驱动模型,其负责完成Domain对硬件设备的访问。其中,位于其它Domain内的前端设备驱动将I/O将I/O请求发送给Domain0(或IDD)内的后端设备驱动,后端设备驱动接收I/O请求,并对其进行安全检查,然后将通过安全检查的I/O请求交由原生设备驱动处理。
设备模型是在Xen支持硬件虚拟化技术后被引入Domain0的,它主要用来处理硬件虚拟机(即VT技术使Guest OS不用修改)Guest OS对设备的访问,设备模型访问的模型主要基于QEMU。
Xen从系统的三个方面进行虚拟化:CPU虚拟化、内存虚拟化、I/O虚拟化
前面提到x86体系结构中,部分敏感指令不是特权指令,这些指令不能自动产生异常,因此想要系统正常运行就必须要捕获这些指令。于是Xen采用修改Guest OS内核的方法对这些有缺陷的指令进行替换。在这种模式下,Xen位于操作系统和硬件之间,为其上运行的Guest OS内核提供虚拟化的硬件环境。这时候,Xen运行在最高特权级的ring0,操作系统被特权解除,运行在ring1,ring3运行应用程序,构成虚拟机系统中的“0/1/3模型”。当Xen占据最高特权级时,在Xen下运行的Guest OS内核将无法运行某些特权指令,并将产生一般保护错误,Xen必须通过超级调用向提供执行这些特权指令的接口。下图是虚拟化前后的特权级的变化。
上述的半虚拟化方法是在最开始没有硬件虚拟化技术支持的情况下的一种解决方案。不过为了克服半虚拟化带来的不便,如:修改Guest OS、性能开销。现在Intel、AMD都在硬件层面上支持虚拟化了,就是我们熟知的Intel VT、AMD VT等技术。在硬件虚拟化技术的支持下,那些原本有缺陷的指令能够直接通过硬件被捕获,也就不需要修改Guest OS内核,从而提高了系统的可移植性。
在半虚拟化模式下,Xen的内存虚拟化通过内存分段保护机制,使得Xen和Guest OS共存于同一个内存地址空间中,简化了Xen对Domain内存的分配和管理工作,同时利用内存分页机制,Xen可保证各Domain在内存上的有效隔离(这是利用了分页机制隔离进程的思想)。下图就是Xen和Guest OS共存的内存地址空间。
Xen需要确保任意两个非特权Domain不会访问到同一内存区虚拟域,因为每一页或页目录的更新必须经过确认,以保证每个Domain只能控制自己的页表。通过修改Guest OS内核,Xen让Guest OS也参与到内存管理的工作中,这样Xen可以更多关注于内存虚拟化中更重要的内存隔离工作,同时也可让硬件MMU在Guest OS的三层地址转换中发挥作用。
上述多次提到虚拟地址到物理地址的三层地址转换,到底这是一种什么样的机制呢?
在传统的系统中,MMU完成虚拟地址到物理地址的转换。操作系统运行需要一段连续的物理地址,用它来映射虚拟地址。但是在Xen中,多个Guest共享整个机器的物理地址。因此,Xen需要让所有操作系统看到一个属于它们自己的连续的物理地址。于是Xen在虚拟地址和机器地址之间引入一层中间地址——客户物理地址。这让Guest OS感觉自己的物理地址是从0开始的连续的地址,然而Xen将这层中间地址真正映射到机器地址却可以是不连续的。这样就保证了所有的物理内存可以被分配给不同的Guest OS了。下图就是三层地址转换示图。
在内存虚拟化中,还有一个非常重要的一环就是内存的分配。在物理内存的管理中,Xen引入了VMware最先采用的气球驱动模型来调节分配给各Domain的物理内存。在半虚拟化模式下,Xen采用了分离设备驱动模型来实现I/O的虚拟化。该模型将设备驱动划分为前端驱动程序、后端驱动程序和原生驱动三个部分,其中前端驱动在DomU中运行,而后端驱动和原生驱动在Dom0(IDD)中运行。前端驱动负责将Guest OS的I/O请求传递到Dom0(IDD)中的后端驱动,后端驱动对I/O请求解析并映射到物理设备,提交给相应的设备驱动程序控制硬件完成I/O操作。
后端驱动检查接收到的I/O请求的有效性,并进行虚拟设备地址到物理设备地址的转换。转换之后,后端驱动将通过Dom0(IDD)中Guest OS提供I/O接口,间接地控制原生设备驱动完成提交的请求。
前端驱动和后端驱动之间I/O请求的传递是通过Xen内部的一个环形队列(I/O环)来实现的,其结构如下图所示。I/O环实际上是Xen提供的一块供DomU和Dom0(IDD)访问的共享内存。
针对大量DMA数据在DomU和Dom0(IDD)之间的高效传递需求,Xen提供了授权表(Grant Table)机制。每个Domain都有一个授权表,用以指明其内部哪些页面可以被哪些Domain所访问。而Xen内部存在一个活动授权表(Active Grant Table)用于缓存来自各Domain授权表的活动表项内容。
当DomU中的Guest OS需要进行DMA操作时,前端驱动会为对应的数据页面生成一个授权描述(Grant Reference, GR)并将授权描述和请求一起放入I/O环。当Dom0(IDD)从I/O环中取出请求时,将根据授权描述,向Xen请求锁定该页面。Xen接收到请求后,在活动授权表或Guest OS的授权表中确认是否已授权特权域访问该页面,通过检查后,表明该页面可安全地进行DMA操作。Dom0(IDD)在接收到Xen的响应后即可开始向真实硬件发送DMA请求了。
参考文献
[1]Xen and the Art of Virtualization. Paul Barham, Boris Dragovic, Keir Fraser, Steven Hand, Tim Harris, Alex Ho, Rolf Neugebauer, Ian Pratt, Andrew Warfield.
[2]Computer Organization and Design The Hardware / Software Interface. David A.Patterson, John L.Hennessy.
[3]http://blog.csdn.net/pi9nc/article/details/11219739
[4]http://blog.csdn.net/dbanote/article/details/8938106#
[5]http://blog.csdn.net/defeattroy/article/details/8802101
[6]http://www.mcplive.cn/index.php/article/index/id/5788/page/5
[7]http://book.51cto.com/art/201003/188412.htm
[8]http://kb.cnblogs.com/page/172315/
[9]http://www.docin.com/p-735988739.html