QEMU 如何在没有引导加载程序的情况下模拟内核?

How does QEMU emulate a kernel without a bootloader?

QEMU 如何准确模拟内核?因为内核需要引导加载程序,但是如果我 运行

qemu-system-x86_64 -kernel kern.bin

它模拟没有引导加载程序的内核。 如果它确实使用引导加载程序,它使用哪个?

我需要知道这个,因为我正在做一个简单的内核,我不想自己写引导加载程序,因为我不知道如何制作引导加载程序,是否可以在一个系统上使用 GRUB USB,它能启动我的内核吗?

-kernel 的行为在来宾体系结构之间有很大差异。在某些(例如 Arm)上,QEMU 通过执行来宾引导加载程序通常会执行的最少必要任务来加载内核:它将文件加载到来宾内存中,将各种寄存器设置为 Linux 内核启动所需的,并且它使用指向内核入口点的程序计数器启动来宾 CPU。 (这有时被称为“内置引导加载程序”。)

在 x86 上,它有点复杂,因为用于 x86 客户机的 QEMU 总是自动运行 BIOS。 x86 -kernel support 我没有仔细看,可能有一些复杂的特例,但是基本的做法是:

  • QEMU 从指定文件加载数据,但不加载到客户机内存中
  • 来宾机器有一个名为 'fw-cfg' 的特殊设备,它充当 QEMU 和来宾代码之间的通信通道
  • 在客户机 ('seabios') 中运行的 BIOS 知道它是 QEMU 上的 运行 并且它知道如何与 fw-cfg 设备通信
  • BIOS 通过 fw-cfg 设备询问“你有什么文件?”,QEMU 说“我有这个 kern.bin”
  • BIOS 通过 fw-cfg 设备将内核文件数据读取到客户机内存中
  • BIOS 启动内核(设置任何必要的寄存器或其他客户机 CPU 状态,并跳转到其入口点)

效果是一样的(“将此文件放入客户 RAM,按照内核记录它需要启动的方式设置环境,跳转到它的入口点”),但是很多更多工作由客户 BIOS 代码完成,而不是直接由 QEMU 完成。