本文首发于稀土掘金。该平台的作者 逐光而行 也是本人。
很多事情,你不知道,并不代表它不存在。正如虚拟化和云计算已经存在很多年了,我还以为它是一个新兴事物。————写在最前面的一点感悟
背景
虚拟化技术实际上并不是一个新奇的概念,它的思想可以追溯到上世纪60年代;
1974年,就已经有人列出了计算机体系结构有效支持虚拟化所需满足的条件,(同期起源的还有x86结构,但后者一直未满足这个条件?);
1999年虚拟机技术突然受到了广泛关注。
分类
虚拟机管理程序分为两类
- 第一类:运行在裸机上
(Hyper-v属于第一种)
- 第二类:依赖于底层操作系统提供的服务和抽象
(VMware属于第二种)
虚拟化技术有效的前提和条件
前提
服务中断不是由硬件层面的缺陷造成。
条件
- 安全。虚拟机管理程序必须完全掌握其下的虚拟资源。
- 保真。其行为像在真机一样。
- 高效:资源由虚拟机管理程序掌握,但是(大部分)代码不应被其干涉。
必要条件:
敏感指令是特权指令的子集
(我的理解:特权指令指的是与内核态相关的指令,这句话的意思是说一些可能引起问题的指令必须仍然交由真机来完成?(即物理硬件陷入))
而针对早期未能实现这一方案的现状,很多看似成功的系统是通过忽视敏感指令,或者修改指令为安全指令完成的,后者的技术也被称为“二进制翻译”。
半虚拟化
半虚拟化并不是模拟物理机底层硬件功能等,而是通过提供一层软件接口来暴露一个虚拟化的环境。
从作用范围看,虚拟化也分为系统级虚拟化和进程级虚拟化。
# 虚拟化详解 ## 开销问题 - 很多虚拟机管理程序为了性能而进行二进制翻译(回顾:将特权指令或非安全代码转化为安全指令及代码),其实不进行二进制翻译虚拟机也能正常运行。 - 二进制翻译后,代码可能变快,也可能变慢。 ## 虚拟机与微内核 第一类虚拟机和微内核之间的界限很模糊。不过**运行在裸机内核态上的程序应该小而可靠**。 ## 内存虚拟化 ### (多级)页表 定义从物理内存空间到虚拟地址空间之间的映射。 通常,操作系统通过设置CPU一个指向顶级页表的控制寄存器来改变映射。 ### Q:如果有多台虚拟机同时映射并请求同一个物理机的物理内存地址该如何? 对每台虚拟机,虚拟机管理程序(以下简称VMP)都要创建一个影子页表。 #### Q:操作系统修改页表后,相关VMP如何及时跟进修改影子页表? (比如修改内存就能修改页表,但并非敏感指令,虚拟机无法察觉) #### 全虚拟化下的解决方案: - VMP跟踪客户机虚拟内存中保存顶级页表的页面。由于客户机首次载入指向顶级页表的硬件寄存器时需使用特权指令,因此虚拟机会察觉,并创建影子页表,将余下部分标为只读。如果客户机修改页表,就会导致**缺页异常**,**控制流交由虚拟机,由虚拟机相应地更新影子页表** - VMP不管客户机修改的事情,但一旦客户机尝试访问新映射的页面,就会发生**缺页异常**,将控制流交给虚拟机。 #### 半虚拟化下的解决方案: 1. 硬件支持嵌套页表(nested page table/extended page table) (我感觉这种方式才是现代操作系统的通用模式,看书上的图类似于微机和计组里面学到的带偏移量的寻址方式+多级链表) 2. 回收内存:气球技术(踢皮球) 气球越大,该范围所能用的实际内存就越小,应该赶紧把大气球踢走 3. I/O虚拟化 每个虚拟机都有一个MAC地址,VMP可以在不同虚拟机之间交换帧。 了解概念:**设备穿透、设备隔离** # 参考资料 《现代操作系统》