浅谈Xen和半虚拟化技术

研究生入学的时候,看了一篇论文——《Xen and the art of virtualization》。如今时隔一年,准备对此进行一番整理。下文是我Xen为例的半虚拟化技术的理解:php


虚拟机概况

首先从虚拟机提及,虚拟机技术最先由IBM于上世纪六七十年代提出,被定义为硬件设备的软件模拟实现。在那个年代,计算机的硬件成本至关大,为了可以提升计算机的利用率,因而提出了这样一种技术:将一台机器经过软件虚拟成多台机器从而为不一样的应用提供服务。现在虚拟机技术应用普遍,可租用的服务器都是使用了不一样方案的虚拟化技术。html

咱们一般提到的虚拟机都是系统虚拟机,如IBM VM/370、VMware ESX Server、Xen。系统虚拟机在二进制指令集系统结构(ISA)的层次上提供一个完整的系统级环境。所以,用户会以为本身在使用整个计算机。一台运行多个虚拟机的计算机能够支持多个不一样的操做系统。在一个传统的平台上,一个单独的操做系统拥有全部的硬件资源,可是经过使用虚拟机,多个操做系统共享硬件资源。前端


虚拟机简介

下图是典型的虚拟机层次结构。它比传统的平台多了一个虚拟机监视器(Virtual Machine Monitor),虚拟机监视器VMM处于硬件和虚拟机层之间。虚拟机监视器VMM负责Host和Guest之间的通讯。在虚拟机系统中,对于上层应用,虚拟机就是真实的计算机。后端


虚拟化分类

虚拟化技术能够分为彻底虚拟化、半虚拟化。缓存

  • 彻底虚拟化
即所抽象的VM具备彻底的物理特性,OS在其上运行不须要任何修改,移植性很是好。可是缺点是效率不高。典型的有VMware,Virtualbox,Virtual PC,KVM-x86。

  • 半虚拟化

起初是为了解决x86体系结构上彻底虚拟化的困难,它须要修改OS,工做效率相对彻底虚拟化要高不少。典型的有Xen、KVM-PowerPC。安全


半虚拟化技术产生的缘由

x86体系是致使半虚拟化技术产生的重要缘由。由于x86指令系统中存在部分敏感指令不是特权指令。什么意思呢?下面来从特权指令和敏感指令的角度进行解释:服务器


  • 特权指令

特权指令是一些操做和管理关键系统资源的指令,这些指令只有在最高特权级上才可以运行。若是在非最高特权级上运行,特权指令会引起一个异常,处理器会陷入到最高特权级,而后由系统软件处理。可是并非全部的特权指令都会引起异常(x86指令系统中的特权指令会有这种问题),最关键的是这些特权指令在不一样的特权级上运行的结果会不同,甚至可能会被直接忽略。架构

  • 敏感指令

传统的机器只有特权指令和普通指令两种概念,而在有虚拟化的机器上则还有一个独特的概念:敏感指令。敏感指令是指在虚拟化时必需要在最高特权级运行的指令。在RISC体系中,全部的特权指令都是敏感指令,所以能够支持彻底虚拟化。可是在x86体系的虚拟化中,部分敏感指令并非特权指令,那么这些非特权指令的敏感指令在系统运行过程当中就不会引起异常,也就没法被捕获并在最高特权级执行。而这些敏感指令在非最高特权级下运行和在最高特权级下运行会有不一样的结果,这对于一个要求性能可靠的计算机不能绝对容忍的。所以,半虚拟化技术,以Xen为先例,主要解决的就是这个问题——如何捕获非特权指令的敏感指令。框架

特权级

上面屡次提到了特权级等概念,下面来进行简要的解释。异步

在操做系统中,咱们常常看到用户态、内核态这些概念,而事实上这两个态的实现就是经过特权级来实现的。以下图所示,如今大部分的计算机体系结构都有两个或两个以上的特权级别,用来分隔内核和应用软件。以x86为例,它拥有4个特权级别(0 to 3),通常用ring来表示。Ring后面的数字越小特权级别越小。在未虚拟化的机器上,Ring0运行操做系统,Ring一、Ring2支持设备驱动,Ring3跑应用程序。而如今的x86处理器中,64位架构已经很是广泛,64位CPU由于必须支持页表模式,因此只须要两个特权级别:ring0、ring3。

Xen虚拟化技术

Xen的总体框架以下图所示。它分为三层,从底层到上层依次是物理层、VMM、Domain。VMM层也就是Xen Hypervisor,负责为上层操做系统提供虚拟化的硬件资源,负责管理和分配这些资源,并确保上层虚拟机(也称为虚拟域Domain)之间的相互隔离。Xen采用混合模式,于是设定了一个特权域用以辅助Xen管理其余的域,并提供虚拟资源服务,该特权域称为Domain0,而其他的域则称为DomainU。


下面按层次来介绍Xen的结构。底层硬件不进行过多赘述。

VMM层

  • 控制接口

控制接口也称为特权控制接口,仅能被Dom0使用,用于帮助Domain0控制管理其余Domain。控制接口提供的具体功能包括Domain的建立。控制接口的具体功能包括Domain的建立、销毁、暂停、恢复及迁移,对其余Domain的CPU调度,内存分配以及设备访问等。

  • 安全硬件接口

提供除虚拟CPU、MMU以外的全部硬件虚拟工做,包括DMA/IO、驱动程序、虚拟的PCI地址配置、虚拟硬件中断等。该接口只能被具备原生设备驱动的Domain使用,而对于其余Domain仅经过设备通道提供虚拟硬件服务。

  • VCPU

Xen为每一个Domain创建了VCPU结构,用以接收Guest OS中传递的指令,其中大部分的指令被VCPU直接提交到屋里CPU执行,而对于特权指令则须要通过确认以后交由Xen代为执行。

  • 虚拟MMU

用于帮助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请求。

  • 独立设备驱动域(IDD)

在最简单的Xen结构中,只存在一个特权域Dom0,这时Xen就好像一个硬件设备抽象层,将复杂的x86架构隐藏起来,全部的硬件设备被Dom0的 Guest OS控制,但这种结构存在很大的问题,若一个特殊设备驱动包含了一些漏洞,那它就有可能摧毁整个Dom0的内核,从而致使整个系统崩溃,为此,将设备驱动 由Dom0移入另外一个虚拟域中,一方面可下降Dom0的运行负载,另外一个方面杨也可减低系统的风险,一旦虚拟域因为使用设备驱动出面故障,Dom0就能够 很方便地重启该虚拟域,这些通过Dom0受权、可以使用特定设备驱动的虚拟域称为独立设备驱动域(Isolated Driver Domain,IDD)。能够避免因为DMA需求和I/O中断对Guest OS形成的影响。

  • 硬件虚拟域(HVM)

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同样,经过修改超级调用页表来发布新的超级调用。

  • 非特权域(DomainU)

严格来说,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虚拟化技术

Xen从系统的三个方面进行虚拟化:CPU虚拟化、内存虚拟化、I/O虚拟化

CPU虚拟化

(1)半虚拟化

前面提到x86体系结构中,部分敏感指令不是特权指令,这些指令不能自动产生异常,所以想要系统正常运行就必需要捕获这些指令。因而Xen采用修改Guest OS内核的方法对这些有缺陷的指令进行替换。在这种模式下,Xen位于操做系统和硬件之间,为其上运行的Guest OS内核提供虚拟化的硬件环境。这时候,Xen运行在最高特权级的ring0,操做系统被特权解除,运行在ring1,ring3运行应用程序,构成虚拟机系统中的“0/1/3模型”。当Xen占据最高特权级时,在Xen下运行的Guest OS内核将没法运行某些特权指令,并将产生通常保护错误,Xen必须经过超级调用向提供执行这些特权指令的接口。下图是虚拟化先后的特权级的变化。


(2)硬件虚拟化

上述的半虚拟化方法是在最开始没有硬件虚拟化技术支持的状况下的一种解决方案。不过为了克服半虚拟化带来的不便,如:修改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的物理内存。
气球驱动可做为驱动程序运行在Guest OS(即Domain)中,Guest OS经过该驱动与Xen通讯。当Domain须要更多内存时,将经过气球驱动向Xen提交内存申请请求,Xen可向气球驱动减压以便将将气球驱动所占用的部分空闲内存或经过气球驱动从其余Domain回收的内存分配给提交请求的Domain。若是Xen的可用空余内存太低,须要从某个Domain回收部分占用的内存,Xen可向气球驱动加压使气球膨胀,Guest OS将回收页面、释放内存以便给本地气球分配足够的内存空间,而后气球驱动将分配到的页面传给Xen,Xen将这些空闲内存集中起来备用。相关的工做原理以下图所示。

I/O虚拟化

在半虚拟化模式下,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请求了。

结语

事实上,计算机领域中遇到的一些问题,不管是软件仍是硬件均可以经过添加一个抽象层来解决,本文中的Xen也是一样如此。


参考文献

[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