内存布局
定义客户机物理内存布局、固定 MMIO 窗口、低内存启动结构的固定位置以及内存容量行为。
译自microsoft/nvx · doc/design/2.3-memory-layout.md。技术细节以英文原文为准。
如图 2.1 所示,客户机 RAM 在后备文件偏移上是连续的,但在客户机物理地址上被固定的 MMIO 窗口分割。
图 2.1. 客户机物理内存布局。
图中各区域按客户机物理地址由低到高排列(对应原图从左到右的方向):
- 低位 RAM
- 地址范围:
0x00000000至0xbfffffff(最高 3 GiB)
- 地址范围:
- 固定 MMIO 窗口
- 地址范围:
0xc0000000至0xffffffff(1 GiB) - 包含:保留的 virtio-mmio 插槽
0xd0000000至0xd0007fff
- 地址范围:
- 高位 RAM
- 地址范围:
0x100000000及以上
- 地址范围:
激活的 RAM 占据 [0, min(size, 3 GiB))。被这 1 GiB MMIO 窗口挤出的内存从 4 GiB 处恢复。不存在高位 MMIO 窗口,也不存在 VTL2 窗口。一个内存布局引擎拥有这一分割,它使用芯片组固定的 MMIO 保留区。它的激活 RAM 范围同时也是快照的内存范围清单,以及用于告诉 Linux 内核哪些物理地址范围是 RAM、哪些是保留的权威 PC 内存映射(e820 映射)。
表 2.4 列出了低内存启动结构的固定位置。
表 2.4. 固定的低内存启动结构。
| 客户机物理地址 | 内容 |
|---|---|
0x0000..0x000f |
Intel MP 1.4 浮动指针 |
0x0400 |
MP 配置表,180 + 20 * 处理器数量 字节 |
0x1000 |
引导 GDT |
0x2000 |
Linux boot_params 零页 |
0x4000..0x9fff |
4 GiB 恒等映射页表:x86-64 页表层级中最上面的两级(PML4 和 PDPT)各一张表,以及四个 2 MiB 页的目录 |
0x20000..0x2ffff |
以 NUL 结尾的内核命令行 |
0x30000..0x30fff |
共享 virtio 中断状态页 |
0x100000 及以上 |
内核加载段和普通 RAM |
e820 映射保留实时中断状态页,以及从 640 KiB 到 1 MiB 的旧版 PC 区间(ISA 空洞),后者容纳显存和固件;它在窗口两侧划分低位与高位 RAM,并且从不把窗口报告为 RAM。加载器写入范围和 DMA 范围必须完全位于某个 RAM 范围之内,且不得跨越 MMIO 窗口或保留的启动结构。
2.3.1 内存容量
快照捕获可以声明一个不可变的 RAM 容量,其大小至少与激活的基础 RAM 相同;随后两个值都按 128 MiB 对齐。布局引擎为完整容量预留地址,但只把激活的基础前缀发布为 RAM,因此选择更大的恢复目标绝不会移动 MMIO 窗口或任何设备。机器契约记录规范的后缀范围,这些范围不存在于已捕获的 e820 映射和内存产物中。跨越 3 GiB 边界的后缀表示为独立的低位 RAM 与高位 RAM 范围。未声明容量的快照在恢复时不能选择不同的 RAM 大小。内存激活 描述了恢复时的序列。