You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我编写的Rust自定义内核无法在QEMU riscv64环境中正常启动?

问题结论

你对QEMU -kernel 参数加载ELF文件的认知是正确的,QEMU确实会解析ELF头部的程序头表加载对应段到内存,然后自动跳转到ELF头中Entry point address字段指定的地址执行,不会直接从内存基地址0x80000000开始执行。你遇到的问题是缺少关键配置导致的。

问题原因&修复步骤

  • 首先确认你给出的启动命令是否完整:你贴出的命令qemu-system-riscv64 -M virt -bios none -kernel 末尾缺少内核文件路径,补全后应为如下格式:
    qemu-system-riscv64 -M virt -bios none -kernel <你的内核ELF文件路径>
    
  • 检查ELF文件的入口地址是否正确
    执行以下命令查看ELF的入口地址:
    rust-readelf -h <你的内核ELF文件路径>
    
    再执行以下命令查看_start函数的实际地址:
    rust-nm <你的内核ELF文件路径> | grep _start
    
    如果两个地址不一致,需要在编译链接参数中添加-e _start显式指定入口符号。
  • 建议添加自定义链接脚本控制内存布局
    默认的Rust裸机编译链接规则没有针对RISC-V virt平台的内存布局做优化,你可以在项目根目录创建link.lds链接脚本,内容如下:
    OUTPUT_ARCH(riscv)
    ENTRY(_start)
    BASE_ADDRESS = 0x80000000;
    
    SECTIONS
    {
      . = BASE_ADDRESS;
      .text ALIGN(4K) : {
        *(.text .text.*)
      }
      .rodata ALIGN(4K) : {
        *(.rodata .rodata.*)
      }
      .data ALIGN(4K) : {
        *(.data .data.*)
      }
      .bss ALIGN(4K) : {
        *(.bss .bss.*)
      }
    }
    
    然后在项目的.cargo/config.toml中添加配置,指定使用该链接脚本:
    [target.riscv64gc-unknown-none-elf]
    rustflags = [
      "-C", "link-arg=-Tlink.lds",
    ]
    
  • 验证执行逻辑:你可以在QEMU启动命令中添加-d in_asm参数,查看QEMU输出的第一条执行指令,确认是否为_start函数中的循环指令,验证跳转逻辑是否正常。

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:42:02