http://www.freehentaihdtube.com

虚拟化虚拟技术原理介绍

  (1) 所有OS设计时都认为Kernel是可以控制所有硬件,并可运行CPU的指令,即Kernel运行于CPU的Ring0上。

  (2) 多个OS无法同时直接运行于硬件层之上,它们必须运行在Hypervisor层(下文称:Host)上;就如同不安装操作系统,

  就不能安装VMware,没有VMware就无法让虚拟机(下文称:Guest)运行起来一样。那问题来了,若GuestOS必须

  (3) OS设计时它认为自己是可以控制所有硬件资源的,那GuestOS之间不就可以相互影响了吗?Guest1要关机,若

  它直接执行CPU的指令关机,那它应该可以关闭整个物理机器,这不是虚拟化所希望的。

  这些问题给CPU虚拟化带来了诸多问题, 但实际上Host一定是真正能执行CPU的指令的,Guest运行起来后,它

  实际控制的CPU是通过软件模拟的CPU,实际上任何物理硬件都是通过集成电进行运算,通过微代码向外提供输出结果

  进行翻译转换后给物理CPU执行.最后返回,这使得GuestOS的执行性能不高.

  》模拟CPU:是完整虚拟,即模拟出CPU的环0,环1,环2,环3;这通常在底层硬件与虚拟的硬件不同时

  》虚拟CPU:仅模拟CPU的环0, Guest的用户空间中的A可直接运行在物理CPU的环3上,仅环0上的

  即Guest不知道自己是运行在虚拟化中,它一直都认为自己是可以控制全部的硬件资源.

  因此需要将GuestOS对指令的操作都进行翻译后,由Host带为执行。

  这样Guest就认为自己是运行在环0上,并且可直接执行指令,但实际上,Guest调用环0上的指令时,

  CPU会直接将其翻译实的指令并激活Host的内核来调用环-1来执行指令,这进一步缩短了

  (1) 在物理机中,内存的使用是经过虚拟化后,提供给物理机上运行的A用的。

  虚拟线性地址空间,即A认为自己使用的是全部的物理内存,从0-1024(假设内存为1G)内核看到的内存是:

  线) 由于物理机的内存已经被虚拟化过了, Guest访问物理内存就需要再次被虚拟一层。

  查询线性与物理地址映射表--缓存映射关系到TLB,并读取物理地址中的数据--返回。

  但GPA并非Host的虚拟线性地址,又非真实物理地址,因此无法由真实CPU处理--

  Host上不得不采用软件模拟来完成将GPA转换实物理内存的物理地址,

  但GuestA和GuestB它们实际映射到Host上的物理内存的地址段肯定是不同的。但GuestA

  访问它的10page的数据若被缓存在TLB中,GuestB到CPU执行时,它恰巧也要访问它的10page的数据

  那TLB中缓存的条目肯定会对GuestB造成干扰,导致访问错误,因此只能将TLB清空,即GuestB到CPU

  上执行时,TLB是空的,因此CPU只能再通过MMU查映射关系,缓存TLB再访问数据。这导致TLB成了摆设

  没有起到提高访问物理内存效率的作用。这才出现了TLB的虚拟化, 而TLB的虚拟化将原先的只有两个

  字段缓存的TLB改成缓存三个字段: 一个GuestOS标识(实际为:VPID),一个GVA,一个HPA(Host中真实物理地址)。

  这样做后,即没有改变GuestOS访问内存的过程,同时提高了GuestOS访问内存的效率。

  了一个标识.用于不同vCPU的地址空间,从而能够区分开Hypervisor和不同处理器的TLB。硬件区分了不同TLB

  项分属于不同的vCPU,因而避免了每次VM调出和调入时,让全部的TLB失效这一动作,加速了VM切换和运行的效率。

  它的虚拟化采用角点当前被谁捕获来模拟的,若当前被虚拟机捕获,则会动态将模拟键盘或鼠标与物理设备关联.

  【注: 这三种技术只针对存储和网络,其I/O设备的模拟不采用这些技术。】》模拟 : 如VMware拿一个文件做为VM的磁盘,这就是模拟。

  Guest-A去访问I/O设备,如网卡,但此时GuestOS明确知道自己不能直接访问到物理网卡,因此,直接将数据转给前端设备(它类似一个转发器,但对GuestOS中的用户看来它是一个网卡设备)--

  后端设备(IO backend):在Hypervisor端从虚拟网卡进程到物理网卡称为后端设备。

  假如规划中该主机上需要运行4台虚拟机,该主机上安装了6块盘,6块网卡,物理机磁盘和网卡都使用两个,

  剩余的都给虚拟机使用,那完全可以给每个虚拟机分一个物理磁盘和一个物理网卡,这样其性能可几乎

  假如当前Hypervisor管理着4块网卡,现在GuestA和GuestB要发送数据到网卡上,GuestA和GuestB都需要借助DMA来代其完成,但DMA是共享式管理,它仅仅负责接收

  Kernel发来的命令然后,根据将指定内存地址中的数据发送到指定IO设备,如网卡,

  或将网卡上收到的数据存入到指定的内存地址中。问题是Guest通过复杂的kernel调用

  过程完成了DMA代其发送数据包到网卡,但GuestOS并不知道DMA将数据包发到那个网卡

  DMA:它的作用是帮助Kernel完成一些需要长时间等待的任务,如:写数据到磁盘,

  从磁盘中读数据到内存,将网卡上收到的数据读到内存等; 这对提供Kernel的执行

  每个IO设备上都有,并且每个IO设备的上都有寄存器且都有相应的端口地址。IOMMU: IO内存地址管理单元

  若需要将某块网卡绑定给某GuestOS单独使用,就需要在Hypervisor级别来控制对I/O端口的调用

  就只能接受该GuestOS的调用了,而它的实现就需要借助DMA中实现IOMMU来完成。而Intel的VT-d

  就是这样一种技术,它在DMA中实现了IOMMU,并自动来完成IO总线与IO端口的映射关联。

  IOMMU的映射是完成将物理IO设备绑定给GuestOS的第一步,接着还需完成将物理IO设备的中断信

  也要映射给该GuestOS,要知道物理设备在实现中断映射通常采用中断 或 DMA等方式实现,而采用DMA方式

  则需要DMA必须能够访问全部的物理内存,因为DMA需要将IO设备的寄存器中的数据搬到指定的内存地址空间

  或反过来;而若将物理硬件绑定给GuestOS,则DMA就需要访问GuestOS的全部物理内存,但实际上GuestOS

  的内存是虚拟的,这就需要经过复杂的转换后才能访问到其对应的物理内存地址空间,这也进一步加大了

  最后一步是完成IO设备缓冲区与GuestOS的映射,这里必须知道缓冲区一定是物理内存中的一段空间,如何让

  虚拟机的内核知道这是自己所管理的物理IO设备的IO缓冲区?;而这一切Intel的VT-d都帮我们实现了。

  IO虚拟化技术: QEMU(法国天才程序员) 、virtio(天才程序员)

  (1) 模拟:【特点:虚拟硬件与底层硬件无关.】著名的模拟器: PrPC, Bochs, QEMU

  通过让网卡工作在混杂模式下,将收到的所有包都接收进来,最后将根据MAC来将数据包发给真实网卡和虚拟网卡。

  

  在x86架构中CPU为了指令的运行,提供了指令的4个不同Privilege级别,术语称为Ring,从Ring 0~Ring 3。Ring 0的优先级最高,可运行所有指令,Ring 3最低。

  而对于一个OS来说它必须是运行在Ring0上的,当然对于GuestOS来说也是如此,因此对于VMM

  就必须模拟让GuestOS认为自己是运行在Ring0上;这样当GuestOS向CPU发送一个指令时,

  VMM(虚拟机器,或叫Hypervisior)必须监测到并调用BT捕获这个指令,在BT进程内部

  并交由宿主OS执行。它最早是由VMware采用的一种动态翻译技术,它将捕获的GuestOS发出的

  指令直接在其进程内部进行转换翻译,最终达到VMM所允许执行的指令,再交由宿主OS执行。

  

  由于VMM并不是所有指令都可捕获,且有些指令执行失败后,并不会返回给GuestOS

  通过硬件实现了直接由CPU自身来实现虚拟化,即VT-x(intel) 和 AMD-V;这两种解决方案的原理是

  一样的,在原先4个CPU等级执行环的基础上新增量一个Ring-1的环,将所有CPU的指令放到Ring-1中,

  无内存虚拟化:在没有虚拟化时,GuestOS要请求内存空间时,它需要将请求的线性地址(虚拟地址:Virtual Address),

  固定运行机制;而在内存虚拟化这种方式下,真机上被虚拟出了一个MMU,将GuestOS的VA(虚拟地址)又转了

  一份给真机虚拟的MMU,由真机虚拟的MMU直接将GuestOS的VA转机的PA,而真机的PA与GuestOS的

  PA之间是建立了一种透明的映射关系,就如:GuestOS的PA2就对应线一样。

  

  真机上虚拟的MMU,又称为影子MMU,它是对MMU芯片的虚拟化;Intel推出了一个EPT

  它们实现的方式是:原先影子MMU实现是这样的,假如现在有A和B两个GuestOS,CPU是轮流分别

  CPU需要将A切到后台,将B切到前台执行,但为了防止B在执行过程中误用A缓存在TLB中的结果,故必须

  将其清空;当GuestOS A再次被调入前台执行时,发现自己的TLB被清空了,因此它会再次向影子MMU

  发出内存空间的请求, 经转换后在经结果缓存在TLB中,这时B的TLB缓存已经被清空了,这使得TLB缓存

  目的变的没有意义了。然而,EPT和NPT他们则通过在TLB中为每个GuestOS加入一个标记位,来区分

  各自的缓存结果,这样每次GuestOS切换回来后,直接在TLB中找到自己的标记就可以获取MMU的转换结果。

  

  PCI硬件设备对VT-d技术的支持与否,决定了VM是否可独占使用该物理设备.并且这种使用

  几乎是不需要Hypervisor参与的。但是要真正实现VM直接使用物理设备,还需要中断重映射

  

  它是Intel为支持虚拟化而设计的I/O虚拟化技术,它可简单理解为替代软件实现的影子页表,但真正执行将GuestOS的虚拟内存地址转换为宿主机的物理地址的硬件芯片是IOMMU。DMAR出现的原因是

  DMA只能访问内存中的低地址空间,而且必须是连续的,这对虚拟化来说很难实现,因此Intel才在其CPU

  

  IOMMA不仅将DMA地址虚拟化,还起到隔离、等作用,如下图所示意,详细请Intel Virtualization Technoly for Directed I/O

  

  来区别设备,因此容易实现,却不容易实现DMA隔离,因此VT-d通过更新设计的IOMMU架构, 实现了多个DMA

  区域的存在,最终实现了DMA虚拟化。这个技术也叫做DMA Repping。

  

  I/O设备会产生非常多的中断请求,I/O虚拟化必须正确地分离这些请求,并由到不同的虚拟机上。

  VT-d实现的中断重映射(interru-repping)架构通过重新定义MSI的格式来解决这个问题,

  新的MSI仍然是一个 DMA写请求的形式,不过并不嵌入目标内存地址,取而代之的是一个消息ID,

  通过一个表结构,硬件可以通过不同的消息ID辨认不同的虚拟机区域。 VT-d实现的中断重映射

  可以支持所有的I/O源,包括IOAPICs,以及所有的中断类型,如通常的MSI以及扩展的MSI-X。

  VT-d进行的改动还有很多,如硬件缓冲、地址翻译等,通过这些种种措施,VT-d实现了北桥芯片

  级别的I/O设备虚拟化。VT-d最终体现到虚拟化模型上的就是新增加了两种设备虚拟化方式:

  

  虚拟机直接分配物理I/O设 备给虚拟机,这个模型下,虚拟机内部的驱动程序

  直接和硬件设备直接通信,只需要经过少量,或者不经过VMM的管理。为了系统的健壮性,需要硬件的

  虚拟化支 持,以隔离和硬件资源只给指定的虚拟机使用,硬件同时还需要具备多个I/O容器分区来

  同时为多个虚拟机服务,这个模型几乎完全消除了在VMM中运行驱 动程序的需求。例如CPU,虽然

  CPU不算是通常意义的I/O设备不过它确实就是通过这种方式分配给虚拟机,当然CPU的资源还处在

  这个模型是I/O分配模型的一个扩展,对硬件具有很高的要求,需要设备支持多个功能接口,

  每个接口可以单独分配给一个虚拟机,这个模型无疑可以提供非常高的虚拟化性能表现。

  运用VT-d技术,虚拟机得以使用直接I/O设备分配方式或者I/O设备共享方式来代替传统的设备模拟/额外设备

  【CPU不支持硬件虚拟化技术:模拟】【CPU支持硬件虚拟化,VMM运行Ring-1,而GuestOS运行在Ring0,

  GuestOS的操作必须先通过System Call转给宿主OS最终将结果,经过多道工序后返回给GuestOS。

  如:GuestOS向外发包时,它先将包封装后发给VMM,有VMM交由宿主OS,经CPU处理最终交由

  让GuestOS内核明确知道自己是工作虚拟中,要使用真实设备,可调用宿主机上专用的系统调用来访问宿主主机的物理硬件,而非自己直接访问【所谓系统调用可简单理解为:驱动】;如:可将GuestOS

  访问物理网卡做成系统调用,当GuestOS需要访问物理网卡时,就可明确告诉它可直接通过系统调用来访问

  物理网卡,这样可绕过宿主OS的参与直接完成访问,其效率更高;由此来说CPU的指令集也是可以做出

  系统调用的,这样做不仅可让GuestOS执行效率更高,而且还可去掉,捕获,及模拟指令集等冗余模块。

  但这就必须涉及到系统内核的修改,因此对于开源的Linux是可行的但对于闭源的Windows则是不可以的。

  

  PV和硬件虚拟化技术结合起来用,可让虚拟化不受OS的;用PV可解决开源OS中CPU的半虚拟化;而Intel的VT-X和AMD的AMD-V可实现对CPU的硬件虚拟化,由硬件来完成GuestOS发出的指令的转换,

  而无需将CPU的指令输出为Hypercall;而对于I/O(磁盘和网卡)和内存依然采用PV的方式实现。

  第一种模型:OS+VMM 实现了Hypervisor的功能。这种是工作站中常见的模型,典型的有VMware Workstations。虚拟技术第二种模型:VMM直接运行在硬件层之上,并提供硬件所需要的所有驱动,同时还提供了一个OS内核

  所必须的各种功能,但这些功能通常是专门为运行在其上的虚拟机而设计的,如:创建,删除虚拟机等。。

  第三种模型:Xen模型,Xen这种模型比较特殊,它虽然直接运行于硬件层之上,但它却并没有提供驱动所有硬件

  的驱动,它仅仅提供了主要设备CPU,Interru(中断),Memory的驱动,因此它采用了一种取巧的方式,

  要安装Xen就先安装一个主虚拟机,由它来驱动底层硬件;而所有虚拟机要访问CPU,Interru,内存时,

  Xen才自己来调度,为每个VM提供服务;在Xen中每台VM都被称为一个Doin,它们安照顺序排列

  

  在Xen模型中Xen将管理GuestOS(GuestOS在Xen中被称为DomU)的功能给了Dom0,当DomU要创建一个网卡,在实现上是在Dom0上创建虚拟网卡软件,DomU仅显示已创建即可,当DomU要访问物理网卡时,DomU实际是先将包发给

  它直接绕过Xen将请求交给物理网卡发出;仅当DomU和Dom0要访问CPU,内存,中断时,才直接有Xen来调度处理。

  

  Xen是原生支持虚拟化的“先锋人物”,若CPU,IO,Memory都不支持硬件虚拟化,Xen也可提供高性能的半虚拟化方案,因为Xen使用Dom0来直接管理硬件,DomU要访问硬件时,先将请求

  Xen是可以直接实现完全虚拟化的,在完全虚拟化中,Dom0可通过软件模拟I/O , CPU指令集 和 硬件,虚拟技术做为DomU的OS也无需修改操作系统的内核就可以直接运行在这种模式下,但其最大的缺点也很明显,就是

  通过软件模拟的硬件性能会很差;但若CPU支持硬件虚拟化,也可在一定程度上提升性能。

  Qemu:Qemu是Dom0用来创建虚拟硬件的主要组件;Qemu最先是由法国的一位天才程序员的可跨的硬件模拟器,其大小1M左右,小巧精悍,如:底层物理处理器是X86,使用Qemu就可模拟

  一个苹果的ARM处理器,甚至是PowerPC处理器,若上层模拟的处理器与物理处理器一致,它还可以

  起到一定程度的硬件加速功能;通常Xen与Qemu共同使用,来为虚拟机建立模拟的网卡,硬盘(它

  XM:它是Xen提供的VM管理工具,如创建,删除,暂停,关闭,快照虚拟机等,XM主要是借助与Xen

  输出的API接口实现这些功能的。XM还可借助Xen的API为虚拟机动态添加CPU,且可模拟多颗,

  KVM最早是以色列的一家软件的,后被Redhat收购,Kernel2.6.20后KVM被整合到Kernel中,加上红帽对它的大力支持,现在KVM也是相对不错的。

  将虚拟OS运行于用户空间,它们就向进程一样,而这些虚拟的GuestOS的所有硬件都是由Qemu模拟出来的,如网卡,硬盘等,GuestOS要访问物理设备,必须先将请求发给Qemu模拟的硬件设备,该设备实际是一个

  用户进程,由模拟的硬件负责将请求发给当前系统的内核来处理,最终由当前OS操作物理网卡完成数据发送。

  

  注意:Qemu它自身完全可以做为一个虚拟服务器使用,但为何不直接使用Qemu,而使用KVM?

  而KVM确是运行在内核空间中的模块,它访问的硬件的速度比用户空间的进程更高效。

  KVM+Qemu:这个组合仅限于位,且CPU必须支持硬件虚拟化(VT-X或AMD-V)。

  Xen最早是由英国剑桥大学主导,现在以被Citrix(思杰)收购【思杰:全球第二大虚拟化解决方案提供商】

  KVM: virtio 是红帽提供的对KVM的I/O半虚拟化的增强技术,目前KVM已经支持透传I/O技术。

  这种虚拟化解决方案是每个用户空间就是一个GuestOS,他们都被模拟出了一个硬盘,网卡等设备,他们使用公共的OS,其性能比两个内核的虚拟化要高的多。但缺点也是很明显的,每个虚拟机之间的

  隔离性较差,若一个VM将OS搞崩溃了,则所有的VM全部都会崩溃;虽有这方面的隐患,但目前其稳定性

  

  模拟硬件层:使用类似于Qemu的工具,虚拟技术来模拟所有GuestOS需要的硬件(如:CPU,内存,硬盘等....)这种方式其迁移将变的非常方便,但其性能很差,这种完全虚拟化方案中Guestos的所有操作都由虚拟硬件翻译后,

  

  5. 最后一种也是第一种模型,其实就类似于VMware Workstation,VirtualBox

  1》等价执行(Equivalient Execution):除了资源的可用性及时间上的不同之外,程序的在虚拟化中

  2》性能(Perfornce):指令集中的大部分指令要能够直接运行于CPU上;

  X86处理器有4个级别,Ring 0 ~ Ring 3,只有运行在Ring 0~2级时,处理器才可访问资源或执行

  指令;运行在Ring 0级时,处理器可以允许所有的指令,x86上的操作系般只使用Ring 0 和

  Ring 3两个级别,其中,操作系统运行在Ring 0级,用户进程在Ring 3级。

  为了满足所述的需求,VMM自身必须运行在Ring 0级,同时为了避免GuestOS控制系统资源,GuestOS

  不得不降低自身的运行级别而运行于Ring 1 或 Ring 3(Ring 2不使用),此外,VMM使用分页或段的方式

  物理内存的访问,但是位模式下段不起作用,而分页又不区分Ring 0,1,2 为了和简化VMM的设计,

  如:指令寄存器)等资源的设置,防止GuestOS运行在Ring 0级,同时又要降级后的GuestOS不受Guest

  设计上的原因,操作系统假设自己运行于Ring 0,然而虚拟化中的GuestOS实际上运行于Ring1或 Ring 3,

  由此,VMM必须各GuestOS不能得知其正运行于虚拟机中这一事实,以免其打破前面的“等价执行”标准,

  例如:x86处理器的级别存放在CS代码段寄存器内,GuestOS却可以使用非PUSH指令将CS寄存器压栈,

  然后,POP出来检查该值;又如:GuestOS在低级别时读取寄存器T,LDT,IDT和TR(这些是CPU内部

  的寄存器,如:指令寄存器...)时并不发生异常,这些行为都不同于GuestOS的正常期望。

  地址空间压缩是指VMM必须在GuestOS的地址空间中保留一段供自己使用,这是x86虚拟化技术面临的另一个挑战。

  VMM可完全运行于自有地址空间,也可部分运行于GuestOS的地址空间,前一种方式,需在VMM模式与GuestOS模式

  之间切换,这会带来较大的开销此外,尽管运行于自己的地址空间,VMM依然需要在GuestOS的地址空间保留出一部分

  来保存控制结构,如IDT和T。无论是哪一种方式,VMM必须自己用到的地址空间不会受到GuestOS的访问后修改。

  x86使用的指令并不完全隶属于指令集,VMM将无确捕获此类指令并作出处理。例如,非指令SM在寄存器

  中存储的机器状态就能够被GuestOS所读取,这违反了经典虚拟化理论的要求。

  x86在某些指令在失败时并不返回错误,因此,其错误将无法被VMM捕获,这将导致其违反经典虚拟化信条中的“等价执行”。

  虚拟化中,屏蔽中断及非屏蔽中断的管理都应该有VMM进行,然而,GuestOS对资源的每次访问都会触发处理器异常,

  这必然会频繁屏蔽或启用中断,若这些请求均由VMM处理,势必会极大影响整体系统性能。

  完整意义上的计算机由硬件和软件共同组成,根据计算机体系结构理论,其硬件包括CPU,内存和各种I/O设备;

  而软件则包括BIOS,操作系统,运行时库及各种应用程序,对于主机虚拟化技术来讲,其主要负责虚拟硬件及BIOS,而

  操作系统,运行时库及各种应用程序可使用以往在物理上各种现在技术及产品。

原文标题:虚拟化虚拟技术原理介绍 网址:http://www.freehentaihdtube.com/kejixinwen/2020/0630/21704.html

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。