为什么我不能在 QEMU 中启动自定义内核?

Why won't me custom kernel launch in QEMU?

我正在考虑创建自己的 OS 用于 hobby/learning 目的。

我创建了一个简单的 Rust 程序,但无法使用 QEMU 启动它。我的 Rust 代码如下所示。

#![no_std]
#![no_main]

mod panic;

#[no_mangle]
pub extern "C" fn _start() -> ! {
    loop{}
}

我正在将其编译为以下格式。

riscv64gc-unknown-none-elf

并尝试在 QEMU 中使用此命令运行它

qemu-system-riscv64 -M virt -bios none -kernel

这将启动 QEMU,但调试工具不会在内存中显示任何内容。

我可以看到它不在内存中的正确位置,因此我向链接器添加了以下参数,以便将其加载到正确的位置(内存的开头)。

--image-base=0x80000000

我可以看到它现在位于正确的位置,但随后不会执行任何操作,因为在 0x80000000 的起始地址处没有有效代码,因为小精灵 header 是那里的第一件事。

我的印象是QEMU能够读取elf文件并跳转到header中指定的入口地址。这不是真的还是我只是遗漏了什么?

QEMU 可能已经确定您的 ELF 文件格式不正确,并退回到“假设这是一个原始二进制文件”。如果你想调试出了什么问题,你可以 运行 gdb 下的 QEMU 并查看从 riscv_load_kernel() 函数开始的代码路径。

不过,更一般地说,QEMU 中的“-kernel”行为依赖于体系结构,但主要是为“启动 Linux 内核”而设计的。因此,如果您确定要构建自定义 OS 以匹配 Linux 使用的图像格式和启动协议,那么它是正确的选择。但是,如果您只是构建一个随机 ELF 文件并想让 QEMU 从它的入口点开始,您可能会发现 generic loader 更合适。