qemu-system-x86_64 -m 4096M
2026/8/16 9:05:23 网站建设 项目流程

通过qemu-system-x86_64 -m 4096M指定的内存大小,最终会进入客户机内核的e820_table中。这是因为 QEMU 在模拟固件时,会主动创建一张 E820 内存映射表,并将你指定的内存作为一个E820_RAM类型的条目添加到这张表中。

QEMU如何生成包含内存的 E820 表

当启动 QEMU 时,它内部会执行一个构建 E820 表的过程。这个过程的核心逻辑在 QEMU 源码的e820_memory_layout.c文件中。

关键的函数是e820_add_entry()。在 QEMU 的启动过程中,它会为虚拟机内存布局中的每个区域调用这个函数,添加对应的条目。通过-m参数指定的 4GB 内存,就是其中最重要的一个区域。QEMU 会调用类似下面的逻辑,将这块内存添加为一个E820_RAM条目:

// 这是 QEMU 内部处理逻辑的示意 e820_add_entry(address_of_your_ram, 4096 * 1024 * 1024, E820_RAM);

QEMU与Seabios/EDK2的协作:通过fw_cfg传递

QEMU 生成这张表后,还需要把它传递给客户机。在现代 QEMU 中,这个传递是通过fw_cfg(Firmware Configuration)接口完成的。

具体的流程是:

  1. QEMU 构建表:QEMU 在初始化内存时,会将指定的 4GB 内存以及 BIOS 保留区域等信息,都通过e820_add_entry()收集起来,构建出一张完整的 E820 表。

  2. 注册为fw_cfg文件:在启动的后期,QEMU 会调用fw_cfg_add_e820()函数,将刚刚构建好的 E820 表作为一个名为"etc/e820"的文件,添加到fw_cfg设备中。这正是看到的 QEMU 源码补丁所做的改进,它确保所有内存区域都添加完毕后,再统一将完整表提供给客户机。

  3. 客户机固件(如 SeaBIOS)读取:虚拟机内的固件(SeaBIOS 或 EDK2)在启动时,会通过fw_cfg接口读取这个"etc/e820"文件。SeaBIOS 固件会优先使用这个来自 QEMU 的动态 E820 表,而不是老旧的 CMOS 方式,来探测内存布局。

  4. 填充struct boot_params:最后,固件会将自己从 QEMU 获取的 E820 表,按照 Linux 内核的启动协议,填充到内核启动参数结构体struct boot_paramse820_table字段中,并将此结构体的指针通过%rsi寄存器传递给内核。

在客户机Linux内核中验证

当 Linux 内核启动后,可以通过以下命令查看 QEMU 传递过来的内存信息:

# 查看内核解析E820表后的内存布局 cat /proc/iomem

在输出中,应当能看到一大块标记为 "System RAM" 的区域,其总大小应和你指定的 4GB 相符。这条信息链证实了:-m 4096M→ QEMU E820表 → fw_cfg → SeaBIOS/EDK2 → Linux内核的e820_table

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询