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

标签 rust qemu elf osdev riscv

出于爱好/学习目的,我正在考虑创建自己的操作系统。

我创建了一个简单的 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 的起始地址处没有有效的代码,因为 elf header 是那里的第一个东西。

我的印象是 QEMU 能够读取 elf 文件并跳转到 header 中指定的入口地址。这是不是真的,还是我只是错过了一些东西?

最佳答案

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

更一般地说,QEMU 中的“-kernel”行为依赖于体系结构,但主要是为“引导 Linux 内核”而设计的。因此,如果您确实要构建自定义操作系统来匹配 Linux 使用的镜像格式和启动协议(protocol),那么它是正确的选择。不过,如果您只是构建一个随机 ELF 文件并希望 QEMU 从其入口点启动,您可能会找到 generic loader更合适。

关于rust - 为什么我不能在 QEMU 中启动自定义内核?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69083040/

相关文章:

rust - 返回包含可变值的结构

email - 使用 Rust lettre 库从 Exchange SMTP 获取 "Client was not authenticated to send anonymous mail during MAIL FROM"错误

linux - QEMU 在哪里映射客户操作系统的内核页面?

linux - 共享库卸载的钩子(Hook)函数

arrays - 为什么用reqwest下载的PNG图像的字节与使用Python下载的字节不同?

macros - 我怎样才能使来自外部 crate 的宏中的 Rust 警告静音?

gdb - 使用 gdbserver 和 qemu 进行调试,如何在控制寄存器 cr3 上设置观察点

assembly - 无需系统调用即可打印字符

c - 如何从程序本身获取指向特定可执行文件部分的指针? (也许与 libelf)

linux - 如何将elf中的地址转换为物理地址