2. 虚拟化基础
好,我们进入第二章。这一章我打算把 QNX Hypervisor(QHV)的骨架拆开给你看。说白了,就是搞清楚它到底是怎么“分身”的,Host 和 Guest 之间是什么关系,以及那个神秘的虚拟化层(VMM)到底在忙什么。
我个人习惯,学一个新系统,先看它的“根”——也就是架构。QHV 的根,就是微内核。
微内核架构:小而精的底气
QNX 的微内核,圈里人都知道,它只做一件事:消息传递。进程间通信(IPC)、中断处理、调度,就这三板斧。其他什么文件系统、网络协议栈、设备驱动,统统扔到用户态去跑。
你想想看,这意味着什么?虚拟化层(VMM)在 QHV 里,其实也是一个用户态进程。它不跑在内核里。这和 Linux 的 KVM 那种内核模块的思路,完全不一样。
核心差异:
- QHV (微内核): VMM 是用户态进程,通过 IPC 与微内核通信。出错了?重启 VMM 进程就行,不会崩掉整个系统。
- KVM (宏内核): VMM 是内核模块。一旦有 bug,恭喜你,内核 panic。
我在项目里遇到过,一个 Guest 的驱动写崩了,直接导致 Host 的 VMM 进程挂掉。但 QNX 微内核纹丝不动,我只需要在 Host 侧重新 spawn 一个 VMM 进程,那个 Guest 就原地复活了。这要是 KVM,整个物理机都得重启。嗯,这就是微内核的底气。
Host OS 与 Guest OS:房东与房客
在 QHV 里,Host OS 是那个拥有物理资源的“房东”。它运行在最高特权级,管理内存、CPU、中断控制器。而 Guest OS 是“房客”,它以为自己独占硬件,其实看到的都是 VMM 伪造的“假硬件”。
关系其实很简单:
- Host OS:负责调度 VMM 进程,分配物理内存给 Guest,处理物理中断。
- VMM:负责模拟 Guest 看到的 CPU、内存、中断控制器、定时器。
- Guest OS:在 VMM 提供的虚拟硬件上运行,完全不知道自己被“骗”了。
我记得有一次调试,Guest 里的 Linux 报了一个“时钟中断丢失”的错误。我一开始以为是 Guest 内核的问题,查了半天。后来才发现,是 VMM 模拟的定时器精度不够,导致 Guest 的 jiffies 计数不准。说白了,是“房东”给的钟慢了。
我的建议: 调试 Guest 问题时,先确认 VMM 模拟的虚拟设备是否正常。很多时候,问题出在“假硬件”上,而不是 Guest 的软件上。
虚拟化层(VMM)的核心组件
VMM 是 QHV 的大脑。它由几个关键组件组成,我列个表给你看:
| 组件 | 职责 | 我的备注 |
|---|---|---|
| vCPU 调度器 | 决定哪个 Guest 的哪个虚拟 CPU 在物理 CPU 上运行 | QNX 的调度策略是优先级抢占 + 时间片轮转,Guest 的 vCPU 本质上就是一个线程 |
| 内存管理单元 (MMU 模拟) | 管理 Guest 的虚拟地址到物理地址的映射,以及物理地址到机器地址的映射 | 这里有两层映射,容易搞混。Guest 的“物理地址”其实是 VMM 分配的虚拟地址 |
| 中断控制器模拟 (GIC/IOAPIC) | 将物理中断分发给正确的 Guest,或者模拟虚拟中断 | 我曾经踩过坑:物理中断直接透传给了 Guest,导致 Host 侧的中断处理函数没执行 |
| 虚拟设备框架 | 提供虚拟网卡、虚拟磁盘、虚拟串口等 | 性能敏感的设备,我建议用“半虚拟化”(virtio),而不是全模拟 |
这里我要强调一下 vCPU 调度器。QHV 的 vCPU 本质上就是一个 pthread。Host OS 的调度器并不知道它在调度一个“虚拟 CPU”,它只知道这是一个普通的线程。所以,如果你给一个 vCPU 线程设置了错误的优先级,它可能会被 Host 侧的其他进程饿死。
避坑指南: 我曾经把一个实时 Guest 的 vCPU 线程优先级设得太低,结果被 Host 侧的一个日志进程抢占了 CPU,导致 Guest 里的控制循环超时。记住:vCPU 线程的优先级,决定了 Guest 的实时性。
资源分区与隔离机制
QHV 的隔离,不是靠“感觉”,而是靠硬件。它利用了 ARM 的虚拟化扩展(VHE)或者 x86 的 VMX 指令集。每个 Guest 都运行在独立的虚拟地址空间里,VMM 通过硬件页表(Stage-2 页表)来隔离不同 Guest 的物理内存。
我画了一张图,帮你理解这个隔离层次:
从这张图你可以看到,隔离是分层的:
- 内存隔离: 每个 Guest 的“物理内存”在 VMM 里是一段连续的虚拟地址。VMM 通过硬件 Stage-2 页表,确保 Guest A 无法访问 Guest B 的内存。这是硬隔离,软件层面无法绕过。
- CPU 隔离: 每个 vCPU 是一个独立的线程。Host OS 的调度器可以给不同的 vCPU 分配不同的 CPU 亲和性(affinity),甚至可以把某个物理核完全独占给一个 Guest。
- 设备隔离: 物理设备可以通过 VMM 的“直通”(passthrough)机制,直接分配给某个 Guest。其他 Guest 无法访问这个设备。
关键点: QHV 的隔离,本质上是“硬件辅助 + 软件策略”的组合。硬件提供页表隔离和特权级隔离,软件(VMM)负责配置这些硬件资源。缺一不可。