• Linux操作系统和内核

操作系统内核设计一直分为两个阵营:微内核和单内核。

单内核是两大阵营中一种较为简单的设计,指的是整个内核从整体上作为一个单独的大过程来实现,并且同时运行在一个单独的地址空间内。所有的内核服务都在这样一个大的内核空间运行,内核之间的通信可以简单地实现为函数调用。这样的设计具有简单高效的特点。但是,如果使用单内核设计,每次对内核作出修改(比如增加或者删除驱动程序),都必须重新编译源代码,生成新的二进制文件,造成了使用和部署上的麻烦。

微内核并不是作为一个单独的大过程来实现的,相反,内核的功能被划分成为多个独立的过程,每一个过程叫做一个服务器。多个服务器程序都运行在自己的地址空间,只有少量核心的服务器运行在特权模式下,服务器之间的通信采用了进程间通信机制。独立的服务器进程提高系统的健壮性,但是进程间通信由于涉及内核空间和用户空间的上下文切换,其开销远比函数调用大得多。

Linux采用了实用主义的设计。为了满足性能要求,Linux内核被设计成单内核。但是,Linux内核同时借鉴了微内核的精华:模块化设计以及动态装载内核模块的能力。除了诸如进程切换、内存管理等核心的内核功能,将大部分内核功能作为单独的内核模块设计并实现。这些内核模块编译好后以单独的二进制文件的形式存在,内核在运行过程中,按照需求,动态地加载并链接进入内核空间运行。不使用的模块还可以在运行的过程中动态卸载。这样的设计,既保证了内核的性能,也改进了传统单内核设计的灵活性。

Linux内核的开放源代码特性及模块化的设计,使其成为很多开发人员和计算机专业学生研究操作系统内核的典型范例。开发人员可以充分利用Linux内核已经实现的成熟功能,在其基础上设计、实现自己的内核模块,以此来扩充内核的功能,满足自己的要求。例如,KVM就是以内核模块的形式存在,为Linux内核增加了虚拟化的功能。


  • X86平台虚拟化的基本模型

wKioJlJ7QhLRCEXRAAA_ZJrDie8920.jpg

使用“虚拟化”一词时,如果没有特殊说明,都是指X86平台的虚拟化。图2-1为大家展示了基本的虚拟化模型。

处于底层是整个物理系统,也就是我们平常看得见、摸得着的系统硬件,主要包括处理器、内存和输入输出设备(这一点相信有主机DIY经验的读者是非常熟悉的)。

在物理系统之上,与以往熟悉的操作系统模型不同,运行的是虚拟机监控器(缩写为VMM或Hypervisor)。虚拟机监控器的主要职能是:管理真实的物理硬件平台,并为每个虚拟客户机提供对应的虚拟硬件平台。

图2-1中绘制了3个虚拟机的实例,每个虚拟机看起来就像是一个小的但是完整的计算机系统,具有自己的“系统硬件”,包括自己的处理器、内存和输入输出设备。在这个计算机系统上,运行着虚拟机自己的操作系统,例如Linux和Windows。

一个X86平台的核心是其中的处理器,处理器运行程序代码,访问内存和输入输出设备。所以,X86平台虚拟化技术的核心部分是处理器的虚拟化。只要处理器虚拟化技术支持“截获并重定向”,内存和输入输出设备的虚拟化都可以基于处理器虚拟化技术之上实现。在处理器虚拟化技术的基础上,为了增强虚拟机的性能,内存虚拟化和IO虚拟化的新技术也不断被加入到X86平台虚拟化技术中。X86平台虚拟化技术从开始单一的处理器开始,逐步牵涉芯片组、网卡、存储设备以及GPU的虚拟化。在2.6节,我们将以Intel硬件平台为例,详细阐述X86平台的硬件虚拟化相关技术的演进。

  • KVM的技术架构

从虚拟机的基本架构上来区分,虚拟机一般分为两种,我们称之为类型一和类型二。

其中,“类型一”虚拟机是在系统上电之后首先加载运行虚拟机监控程序,而传统的操作系统则是运行在其创建的虚拟机中。

与“类型一”虚拟机的方式不同,“类型二”虚拟机监控程序,在系统上电之后仍然运行一般意义上的操作系统(也就是俗称的宿主机操作系统),虚拟机监控程序作为特殊的应用程序,可以视作操作系统功能的扩展。

KVM是一个基于宿主操作系统的类型二虚拟机。在这里,我们再一次看到了实用至上的Linux设计哲学,既然类型二的虚拟机是最简洁和容易实现的虚拟机监控程序,那么就通过内核模块的形式实现出来就好。其他的部分则尽可能充分利用Linux内核的既有实现,最大限度地重用代码。在图2-2中,左侧部分是一个标准的Linux操作系统,可以是RHEL、Fedora、Ubuntu等。KVM内核模块在运行时按需加载进入内核空间运行。

wKioOVJ7QkCSSUh7AABBoEEBhU8819.jpg

  • KVM的组成要素

KVM模块是KVM虚拟机的核心部分。其主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚拟客户机的运行提供一定的支持。

  1. 以KVM在Intel公司的CPU上运行为例,在被内核加载的时候,KVM模块会先初始化内部的数据结构;

  2. KVM模块检测系统当前的CPU,然后打开CPU控制寄存器CR4中的虚拟化模式开关,并通过执行VMXON指令将宿主操作系统(包括KVM模块本身)置于虚拟化模式中的根模式;

  3. 最后,KVM模块创建特殊设备文件/dev/kvm并等待来自用户空间的命令。

  4. 接下来虚拟机的创建和运行将是一个用户空间的应用程序(QEMU)和KVM模块相互配合的过程。

KVM模块与用户空间QEMU的通信接口主要是一系列针对特殊设备文件的IOCTL调用。

QEMU本身并不是KVM的一部分,其自身就是一个著名的开源虚拟机软件。与KVM不同,QEMU虚拟机是一个纯软件的实现,所以性能低下。但是,其优点是在支持QEMU本身编译运行的平台上就可以实现虚拟机的功能,甚至虚拟机可以与宿主机并不是同一个架构。作为一个存在已久的虚拟机,QEMU的代码中有整套的虚拟机实现,包括处理器虚拟化、内存虚拟化,以及KVM使用到的虚拟设备模拟(比如网卡、显卡、存储控制器和硬盘等)。

  • KVM实现所依赖的硬件虚拟化技术进化蓝图

Intel虚拟化技术其实是一系列硬件技术的集合,虚拟机监控机软件通过选择利用各项技术,从而提高虚拟化软件的性能或者实现各种不同的功能。

Intel虚拟化技术其实可以大致分为三类:第一类是处理器相关的,称为VT-x,是实现处理器虚拟化的硬件扩展,这也是硬件虚拟化的基础;第二类是芯片组相关的,成为VT-d,是从芯片组的层面为虚拟化提供必要支持,通过它,可以实现诸如直接分配物理设备给客户机的功能;第三类是输入输出设备相关的,主要目的是通过定义新的输入输出协议,使新一代的输入输出设备可以更好地支持虚拟化环境下的工作,比如Intel网卡自有的VMDq技术和PCI组织定义的单根设备虚拟化协议(SR-IOV)。

参考: http://book.51cto.com/art/201311/416131.htm