本文主要是写给新接触xen的开发者及想深入了解xen的人。
xen vmm(virtual machine monitor)是由剑桥大学计算机实验室开发的一个开源项目,它能够让我们创建更多的虚拟机,每一个虚拟机都是运行在同一个操作系统上的实例。
这些客户os可以是修补过的linux内核2.4或2.6,也可以是修补过的netbsd/freebsd内核。用户应用程序就运行在这些客户os上,并不需要修改任何代码。
我曾经紧密跟踪xen项目一年多。对xen产生兴趣是在读了2004年的ols(ottawa linux symposium)论文集之后。
完全虚拟化已经被一些硬件仿真程序实现了。硬件仿真器的不利因素是它们的性能。
xen项目(半虚拟化)的思想已经不是很新鲜了。性能度量和它达到的高效性,能够被看作是一个突破,运行xen的系统开销确实非常小,大约占3%。
就像刚才所说的那样,现在的xen要为内核打补丁,但是,将来的处理器能支持虚拟化,内核也就不需要打补丁了。比如说,intel的vt和amd的pacifica处理器都将包括这种支持。
xensource公司2005年8月在intel开发者论坛(idf)上发表声明说,它已经利用intel的vt-enabled平台和xen技术虚拟化了linux和windows xp sp 2。
如果没有其它虚拟化方法的话,intel的vt和amd的pacifica将会在对xen的支持上展开竞争。
同时参与竞争的还有vmware公司的esx server,它不是基于xen的虚拟化解决方案。vmware公司2005年8月初声明,他将通过一个叫vmware community source的计划允许他的合作伙伴使用vmware esx server的源代码和接口。
vmware的一个显著优势就是它不需要在客户os上打补丁。vmware可能比xen运行地慢一些,因为它使用影子页表(shadow page tables),而xen同时使用直接和影子页表。
xen已经在像fedora core 4、debian和suse professional 9.3这些产品中捆绑发行了,它也将被包含在rhel 5中。
针对其它处理器的支持正在有条不紊地进行着。xen小组致力于x86_64 port,同时ibm着手于提供power 5芯片的支持。
保护环
在xen中,一个“系统管理程序”运行在0环,客户os运行在1环,应用程序运行在3环。这种关系对于x64/64有一点不同,就是客户内核和应用程序都运行在3环上。
xen自身被称为“系统管理程序”,是因为它比客户os的系统管理代码运行所需的特权级还高。
当系统引导的时候,xen被装载到0环的内存中。它在1环上启动修补过的内核,这被称作是domain 0(译者注:domain是指一个运行中的虚拟机,在其上有一个guest os在执行)。从这个domain开始,你可以创建更多的domain,也可以销毁它们,可以进行domain的迁移、设置参数等等。你创建的那些domain也运行在1环它们的内核中。用户应用程序运行在3环。

目前,修补过的linux内核2.4和2.6可以作为domain 0。据xen开发者所说,将来domain 0仅支持2.6的内核补丁。构造domain 0的大部分工作是在xen/arch/x86/domain_build.c中的construct_dom0()方法中实现的。
物理设备驱动程序只能运行在特权级,也就是domain 0上。xen依靠linux或其它修补过的os内核对它所有的设备提供虚拟化支持。这样的好处就是xen的开发者不必再去开发设备驱动程序。
在一个有标签tlb的处理器上使用xen能够大大提高性能。标签tlb能够把asid(address space identifier)放在tlb入口处。有了这个特性,当处理器在系统管理程序和客户os之间切换时就不需要刷新tlb了,这大大减少了系统开销。
xend deamon
首先,我们介绍一下xend,它是xen控制器daemon,意思是说它负责处理创建、销毁、迁移以及其它许多domain管理的任务。它很大一部分动作是基于一个http服务器的。大量对domain的控制请求都是通过发送http请求来实现的。
我们在引导进入xen后通过命令行命令xend start来启动xend daemon。它需要python2.3的支持。
xend daemon的工作是建立在与xcs server(the control switch)的交互上。所以,当我们启动xend daemon时,需要检查一下xcs是否已经启动和运行了。如果没有,我们将试着去启动它。
srv daemon是xend的主要程序,启动xend daemon就会创建一个srv daemon类的实例。
接下来在createfactories()方法中创建一个channel factory。channel factory有一个隐含的notifier对象。xend daemon的大量工作都是基于这个notifier接收的消息的。这个factory创建一个线程,在一个无限循环中读取这个notifier。
创建domain
创建一个domain是通过使用一个hypercall(dom0_createdomain)来完成的。hypercall是linux内核中的一个系统调用,通过它,用户空间可以调用内核中的方法,它通过一个中断(int 0x80)来完成。在xen中,类似的系统调用就是hypervisor,通过它,domain 0 调用hypervisor中的方法,它也是通过中断(int 0x82)来完成的。hypervisor通过它的虚拟cpu访问每一个domain。
xenddomain类和xenddomaininfo类在创建和销毁domain中扮演着非常重要的角色。我们通过调用xenddomain中的domain_create()方法创建一个新的domain。
xenddomaininfo类和它的方法主要用于一个domain的实际构造。
xcs server
xcs server有两个tcp套接字,分别是控制连接和数据连接,它们不同的地方在于前者是同步的,后者是异步的。前面提到的notifier对象,就是xcs服务器的一个客户端。
创建虚拟设备
xenddomaininfo中的create()方法启动一个创建domain的动作链。首先被创建的是这个domain的虚拟设备。这个create()方法调用create_blkif()创建一个块设备接口(blkif),即使vm不需要磁盘它也是必须被创建的。另一个虚拟设备通过create_configured_devices()创建。
所有的设备类都从dev继承,dev是一个联系设备控制器的抽象类。它的attach()抽象方法在每一个dev类的子类中实现,这个方法把前端和后端联系了起来。图2展示了设备的层次,图3展示了设备控制器的层次。


domain 0运行后端驱动,同时最新创建domain运行前端驱动。许多消息在后端和前端驱动之间传送。前端驱动感觉上是虚拟的,它不需要使用特定硬件的详细信息。
联系虚拟设备的中断是虚拟中断。
结论
xen项目是一个很有趣同时充满了希望的项目。它的代码很复杂,特别是虚拟内存管理、活动域合并工具和授权表机制。本文仅仅是介绍性的,并不涉及这些话题。然而,我希望它能够成为想要了解和深入研究代码的一个出发点。
闽公网安备 35060202000074号