在硬件与操作系统之间的是硬件抽象层,在操作系统与应用程序或函数库之间的是API抽象层。硬件抽象层是计算机中软件所能控制的硬件抽象接口,通常包括CPU的各种寄存器,内存管理模块,I/O端口和内存映射的I/O地址等。API抽象层抽象的是一个进程所能控制的系统功能集合,包括穿件新进程,内存申请和归还,进程间同步与共享,文件系统和网络操作等。
系统虚拟化是指将一台物理计算机系统虚拟化为一台或多台虚拟计算机系统。每个虚拟计算机系统(简称虚拟机)都拥有自己的虚拟硬件(如CPU,内存和设备等),来提供一个独立的虚拟机执行环境。通过虚拟化层的模拟,虚拟机中的操作系统认为自己仍然是独占一个系统在运行。每个虚拟机中的操作系统可以完全不同,并且他们的执行环境是完全独立的。这个虚拟化层被称为虚拟机监控器(Virtual Machine Monitor,VMM)
虚拟机监视器(VMM)是一个系统软件,可以维护多个高效的、隔离的程序环境,该环境支持用户直接去访问真实硬件,而这样的程序环境就称为虚拟机。
从本质上,虚拟计算机系统和物理计算机系统可以是两个完全不同的ISA系统。但是,不同的ISA使得虚拟机的每一条指令都需要在物理机上模拟执行,从而造成性能下降。相同体系结构的系统虚拟化通常会有比较好的性能,VMM实现起来也会比较简单
云计算的一个核心思想就是在服务器端提供集中的计算资源,同时这些计算资源要独立地服务于不同的用户,也就是在共享的同时,为每个用户提供隔离、安全、可信的工作环境。虚拟化技术奖是云计算的一个基础架构。通俗地说,云计算实际是一个虚拟化的计算资源池,用来容纳各种不同的工作模式,这些模式可以快速部署到物理设备上。虚拟化的资源按照来自用户的需求多少动态调用资源,每个用户都有一个独立的计算执行环境。
在没有虚拟化的环境中,操作系统直接负责物理处理器管理,负责进程间调度和切换。但是,VMM接管物理处理器后,客户机操作系统没有管理物理处理器的权利,可以说此时它已经运行在VMM为之涉及的虚拟处理器上,管理虚拟处理器,并在虚拟处理器上负责该虚拟机内进程间调度和切换。
虚拟处理器的功能可以由物理处理器和VMM共同完成。对于非敏感指令,物理处理器直接解码处理请求,并将相关效果反应到物理寄存器上;而对于敏感指令,VMM负责陷入再模拟(是不是可以理解为敏感指令保存在虚拟寄存器,非敏感指令保存在物理寄存器上?)
在没有虚拟化的环境里,对称多处理技术可以让操作系统拥有并控制多个物理处理器,它通过提供并发的计算资源和运算逻辑,允许上层操作系统同时调度多条基于不同计算目的的进程并发执行,从而有效提高系统的吞吐率和性能。同理,当物理计算资源足够多时,VMM可以考虑为虚拟机呈现出多个虚拟处理器,也就是客户对称多处理器虚拟化技术,也称SMP技术。
在没有虚拟化的情况下,操作系统在对内存的使用与管理上达成了两点认识:(1)内存都是从物理地址0开始的;(2)内存都是连续的,或者说至少在一些大的粒度(如256M)上连续。而对于虚拟环境中,由于物理地址为0的只有一个,无法同时满足所有客户机操作系统内存从0开始的要求。VMM要做的就是欺骗客户机操作系统,让谎言满足客户机操作系统对内存的两点要求,这种欺骗过程,就是内存虚拟化。
引入了客户机物理地址空间,内存虚拟化就主要处理以下两个方面的问题:(1)给定一个虚拟机,维护客户机物理地址到宿主机物理地址之间的映射关系(2)截获虚拟机对客户机物理地址的访问,并根据所记录的映射关系,将其转换成宿主机物理地址
完全虚拟化通过Binarary Trasnlation在二进制代码级别上来避免虚拟化漏洞,类虚拟化采用修改操作系统内核的代码(即API级),使得操作系统内核完全避免这些难以虚拟化的指令
由于硬件体系结构在虚拟化方面设计存在缺陷,导致了虚拟化漏洞,为了进行弥补,在硬件还未提供足够的支持之前,基于软件的虚拟化技术给出了两种可行的解决方案:模拟执行和直接源代码改写。模拟执行对应的就是基于软件的完全虚拟化技术,直接改写源代码对应的是类虚拟化技术
自伸缩内存调节技术:VMM通过诱导客户机操作系统来回收和分配客户机所拥有的宿主机物理内存技术。具有气球模块,申请客户机物理内存,但并不真正有效地使用它们,而是通知VMM这些客户机物理内存对应的宿主机物理内存可以被回收。
页共享技术:在一台物理主机上运行多个客户机,VMM可以通过页共享技术节省宿主机物理内存资源
设备模型是位于虚拟机设备驱动程序与实际设备驱动程序之间的一个模块,由设备驱动所发出的I/O请求先通过设备模型模块转化为物理I/O设备的请求,再通过调用物理设备驱动来完成相应的I/O操作。反过来,设备驱动将I/O操作结果通过设备模型模块,返回给客户机操作系统的虚拟设备驱动程序。
第二章 x86架构及操作系统概述
2.1-2.2
分段机制:由四个基本部分构成,逻辑地址,段选择寄存器,段描述符,段描述符表。
段选择符
Index:段描述符表的索引
TI:用于指明索引哪个段描述符。0为GDT,全局描述符表;1为LDT,本地描述符表
段描述符
描述某个段的基地址、长度和各种属性。当CPU通过一个逻辑地址的段选择符获得该段对应的段描述符后,会使用描述符中各种属性字段对访问进行检查,一旦访问被确认合法,CPU将段描述符中的32基地址和逻辑地址中的32位偏移量想加以获得该逻辑地址对应的线性地址。
段描述符表
x86架构提供两种段描述符,全局段描述符表(GDT)和本地段描述符表(LDT)。
为了加速对GDT和LDT的访问,x86提供了GDTR寄存器和LDTR寄存器,描述为:GDTR:包括一个32位的基地址(BASE)和一个16位长度(LIMIT),LDTR:结构同段寄存器(包括对程序不可见的段描述符寄存器)
分页机制让现代操作系统中的虚拟内存机制成为可能,一个页面可以存在于物理内存中,也可以存放在磁盘交换区域(如linux下的Swap分区,Windows下的虚拟内存文件),程序可以使用比机器物理内存更大的内存区域。操作系统在启动过程中,通过将CR0寄存器的PG位置1来启动分页机制
分页机制,一个4KB的页面使用两级页表
页目录项:包含页表的物理地址,CPU使用线性地址的22-31位索引页目录,获得线性地址对应的页目录项
页表项:包含该线性地址对应的PFN(物理页帧号),页表项存放在页表中,CPU使用线性地址12-21位索引页表,获得该线性地址对应的页表项
CPU在索引页目录前,必须知道页目录所在的物理地址,该物理地址存放在CR3寄存器,也称为页目录基地址寄存器(PDBR)
TLB:旁路转换缓冲区。为了提高地址转换的效率,x86架构使用TLB对最近用到的页面映射进行缓存,当CPU访问某个线性地址,其所在页面的映射存在于TLB中,无须查找页表即可进行地址转换。当操作 系统对页表进行修改后,要负责对TLB中对应的条目进行刷新,以保证缓存的一致性。刷新方式有:(1)更新CR3,TLB整体刷新(2)INVLPG指令,对TLB单独页目录项,页表项刷新
总结以上即为:CPU先访问TLB缓存,若有对应项,从TLB中得到物理地址,如果没有对应项,CPU在访问页表,如果在页表中有对应项,在页表中得到对应的物理地址,如果没有对应项,产生缺页中断,用调度算法从磁盘中获取页面
x86四种运行模式:实模式,保护模式,SMM模式和虚拟8086模式。
实模式:CPU加电经历最初混沌状态,首先进入实模式。操作系统或BIOS通常在该模式下准备必要的数据结构和初始化关键寄存器,然后切换进入保护模式
保护模式:操作性运行时最常用的模式,CPU所有功能几乎都能使用,可以访问架构允许的所有物理地址空间
操作系统对中断/异常的处理流程
一个中断/异常发生,打断当前正在执行的任务
(1)CPU通过vector索引IDT表得到对应的门,并获得其处理函数的入口地址
(2)程序跳转到处理函数执行,由于处理函数存放在CPL=0的代码段,程序可能会发生权限提升,处理函数通常执行下列几个步骤
i 保存被打断任务的上下文,并开始执行处理函数;
ii 如果是中断,处理完成后需要写EOI寄存器(伪中断不需要)应答,异常不需要
iii 恢复被打断的任务上下文,准备返回
(3)从中断/异常的处理函数返回,恢复被打断的任务,使其继续执行
进程:尽管表面上看起来程序和进程非常类似,但本质上他们是截然不同的。程序是指一个静态的指令序列,而进程则是一个容器,其中包含了当执行一个程序的特定实例时所用到的各种资源
上下文切换是指程序从一种状态切换到另一种状态,或从一个程序切换到另一个程序(例如进程切换)时,导致上下文相关寄存器值的变化行为,这种变化是指就程序上下文相关寄存器的值被保存到内存中,新程序上下文寄存器的值被加载到寄存器中。通常只有三种情况:用户态到内核态的切换;进程切换;到中断上下文的切换
中断的处理函数运行在特殊的上下文环境,称为中断上下文
设备通过寄存器和设备RAM将自身的功能展现给CPU,CPU读写这些寄存器和RAM即可完成对设备的访问和操作。
DMA(直接内存访问)是将CPU从I/O操作中解放,通过DMA,驱动程序可以事先设定一个内存地址,设备就可以绕开CPU直接向内存中复制或读取数据。DMA可以分为两种:(1)同步DMA:是指DMA操作由软件发起(2)异步DMA:是指DMA操作由设备发起
第三章 虚拟化概述
传统的虚拟化技术一般是通过陷入再模拟的方式实现的,而这种方式依赖于处理器的支持,也就是说,处理器本身是否是一个可虚拟化的体系结构。VMM对物理资源的虚拟可以归结为三个主要任务:处理器虚拟化,内存虚拟化和I/O虚拟化
虚拟环境由三个部分组成:硬件,VMM和虚拟机。在没有虚拟化的情况下,操作系统直接运行在硬件之上,管理底层的物理硬件,这就构成了一个完整的计算机系统,也就是所谓的“物理机”。在虚拟环境里,虚拟机监控器VMM抢占了操作系统的位置,变成了真是物理硬件的管理者,同时向上层的软件呈现出虚拟的硬件平台,而此时操作系统运行在虚拟平台上,仍然管理着它认为是“物理硬件”的虚拟硬件。
特权指令:系统中有一些操作和管理关键系统资源的指令,这些指令只有在最高特权级上才能正确运行。
敏感指令:操作特权资源的指令,包括修改虚拟机的运行模式,读写时钟,中断等寄存器。主要是在虚拟化场景下,客户机OS内核的特权被解除,从原来的0降到1或者3,这部分特权指令在客户机OS中发生时,就会产生Trap,被VMM捕获,从而由VMM完成。虚拟化场景中敏感指令必须被VMM捕获并完成。对于一般 RISC 处理器,如 MIPS,PowerPC 以及 SPARC,敏感指令肯定是特权指令,但是x86 例外,但是x86绝大多数的敏感指令是特权指令,但是由部分敏感指令不是特权指令,执行这些指令的时候不会自动trap被VMM捕获
陷入再模拟:如果一个系统上所有敏感指令都是特权指令,则能够用一个简单的方法来实现一个虚拟环境:将VMM运行在系统的最高特权级上,而将客户机操作系统运行在非最高特权级上,当客户机操作系统因执行敏感指令(此时,也就是特权指令)而陷入到VMM中,VMM模拟执行引起一场的敏感指令,这种方法被称为“陷入再模拟”
虚拟化漏洞:判断一个结构是否可虚拟化,核心在于该结构对敏感指令的支持上,如果某些结构上所有敏感指令都是特权指令,则它是可虚拟化结构,否则如果它无法支持在所有的敏感指令上触发异常,则不是一个可虚拟化结构,称其存在虚拟化漏洞
当客户机操作系统试图访问关键资源时,该请求不会真正发生在物理寄存器上,相反,VMM会通过准确模拟物理处理器的行为,而将其访问定位到VMM为其设计与物理寄存器相应的“虚拟”寄存器上。例如:当处理器取指令MOV CR0,EAX后,发现特权级别不符合,则抛出异常,VMM截获这个异常之后模拟处理器的行为,读取EAX内容并存放到虚拟的CR0中,由于虚拟CR0存放在VMM为该虚拟机设计的内存区域里,因此该指令执行的结果不会让物理的CR0内容改变,等到下一次虚拟机试图读CR0时,处理器也会抛出异常,然后由VMM从虚拟的CR0而不是从物理的CR0中返回内容给虚拟机
对称多处理技术:可以让操作系统拥有并控制多个物理处理器,它提供并发的计算资源和运算逻辑。即有多个CPU可以并发执行。当物理计算资源足够多时,VMM也可以考虑为虚拟机呈现出多个虚拟处理器,也就是客户对称多处理器虚拟化技术,也称客户SMP技术。
在没有虚拟化的情况下,操作系统在内存的使用和管理上达成了两点认识:内存都是从物理地址0开始的;内存都是连续的,或者说至少在一些大的粒度(如256MB)上连续。
为了更有效的利用空闲的物理内存,尤其是系统长期运行后产生的碎片,VMM通常会以比较小的粒度(如4KB)进行分配,这就造成了给定一个虚拟机的物理内存实际上是不连续的问题,其具体位置完全取决于VMM的内存分配算法。
引入了客户机物理地址空间,内存虚拟化就主要处理两个方面的问题:给定一个虚拟机,维护客户机物理地址到宿主机物理地址之间的映射关系;截获虚拟机对客户机物理地址的访问,并根据所记录的映射关系,将其转换为宿主机物理地址。
客户机操作系统采用客户页表维护客户机虚拟地址到客户机物理地址的映射:GPA=f1(GVA),GVA为客户机虚拟地址,GPA为客户机物理地址。而VMM负责客户机物理地址到宿主机物理地址之间的映射:HPA=f2(GPA),HPA表示宿主机物理地址
I/O虚拟化:现实中外设资源是有限的,为了满足多个客户机操作系统对外设访问的需求,VMM必须通过I/O虚拟化的方式复用有限的外设资源,在面临这种问题时,VMM所要做的是模拟,即截获客户操作系统对设备的访问请求,然后通过软件的方式模拟真实物理设备的效果,仍然是欺骗客户机操作系统,这种模拟过程,就是I/O虚拟化。
设备发现就是要让VMM提供一种方式,来让客户机操作系统发现虚拟设备, 这样客户操作系统才能加载有关的驱动程序,这是I/O虚拟化的第一步
VMM实现虚拟机间的通信机制,并向虚拟机提供相应的API。虚拟机的客户机操作系统通过调用这些API与其他虚拟机进行通信。VMM除了提供虚拟机之间通信的API外,也提供虚拟机与VMM之间交互的API
类虚拟化技术,其主要思想是通过客户机操作系统与虚拟化管理层的协同设计,由虚拟化管理层软件提供一个近似于原物理系统,但又不完全相同的虚拟平台,以表面虚拟化漏洞和实现更高的虚拟化效率。虚拟化技术需要修改操作系统的源代码来与下层的虚拟化管理层软件协同工作,从而避免体系结构上的缺陷
VMM按照虚拟平台分类,可分为:完全虚拟化和类虚拟化。前者是虚拟平台可以运行现有的操作系统,不需要对操作系统进行任何修改,后者是平台在现实中不存在,而是通过VMM重新定义,这样的虚拟平台需要对所运行的客户机操作系统进行或多或少的修改使之适应虚拟环境
类虚拟化:通过在源代码级别修改指令以回避虚拟化漏洞的方式来使VMM能够对物理资源实现虚拟化。对于x86一些难以虚拟化的指令,完全虚拟化通过在二进制代码级别(扫描客户机二进制代码,将难以虚拟化的指令转化为支持虚拟化的指令)上来避免虚拟化漏洞。类虚拟化采取修改操作系统内核的代码(即API级),使得操作系统内核完全避免这些难以虚拟化的指令
VMM实现结构分类:(1)Hypervisor模型:优点:VMM同时具备物理资源的管理功能和虚拟化功能,因此,物理资源虚拟化的效率会更高。虚拟机的安全只依赖于VMM安全;缺点:VMM由于完全拥有物理资源,因此VMM需要进行物理资源的管理,包括设备驱动,而对于设备驱动开发的工作量很大,因此任务量较大。(2)宿主模型:物理资源由宿主机操作系统管理。宿主机操作系统是传统的操作系统,如windows,linux等,这些传统的操作系统并不是为虚拟化而设计的,因此本身不具备虚拟化功能,实际的虚拟化功能由VMM来提供。最大的优点是可以充分利用现有操作系统的设备驱动程序,VMM无须为各类I/O设备重新实现驱动程序。但缺点在于,安全方面,由于VMM是宿主机操作系统内核的一部分,因此,如果宿主机操作系统内核是不安全的,VMM也是不安全的。(3)混合类型:上述两种模式的混合体。VMM依然在最底层,拥有所有的物理资源,但是VMM会主动让出大部分I/O设备控制权,交由一个运行在特权虚拟机中的特权操作系统控制
第四章 基于软件的完全虚拟化
解释执行:在模拟技术中,最简单的模拟技术是解释执行,即取一条指令,模拟出这条指令执行的效果,再继续取下一条指令,由于一条一条取指令不会漏过每一条指令,在某种程度上即每条指令都陷入了,所以解决了陷入再模拟的问题,进而避免了虚拟化漏洞。但虽然这种方法保证了所有指令执行受到VMM的监视控制,然后它对每条指令不区别对待,其最大的缺点就是性能太差。
扫描和修补:由于解释执行有很大的性能损失,加上虚拟机中模拟的CPU和物理CPU体系结构是相同的,这样大多数指令可以被映射到物理CPU上直接运行。扫描和修补技术即通过这样的方式,让大多数指令直接在物理CPU上运行,而把操作系统代码中的敏感指令替换为跳转指令或会陷入到VMM中去的指令,使其一旦运行到敏感指令处控制流就会进入VMM中,由VMM代为模拟执行。流程如下:(1)VMM会在虚拟机开始执行每段代码之前对其进行扫描,解析每一条指令,查找到特权指令和敏感指令(2)补丁代码会在VMM中动态生成,通常每一个需要修补的指令会对应一块补丁代码(3)敏感指令被替换成一个外跳转, 从虚拟机跳转到VMM的空间里,在VMM中执行动态生成的补丁代码(4)当补丁代码执行完后,执行流再跳转回虚拟机中的下一条代码继续执行
扫描与修补原理:大部分指令都能被物理CPU载入执行,但对于一些敏感指令将会被VMM替换为外跳转,其对应一块补丁代码,外跳转将会执行补丁代码,从而模拟指令的功能
二进制代码翻译
将客户机操作系统代码放置在缓存中,不会被物理机CPU直接执行
内存虚拟化的目的:提供虚拟机一个从零开始的连续的物理内存地址;各个虚拟机之间有效隔离,调度以及共享资源
VMM为每个虚拟机动态维护一个从客户机物理地址到宿主机物理地址的表,使得多个虚拟机之间相互隔离,可以各自拥有从零开始的物理内存地址。VMM截获对客户机物理地址的访问,将其访问为宿主机对应的物理地址。
影子页表就是一种对应的客户机虚拟机地址到宿主机物理地址的映射表