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

QEMU RISC-V环境下用C语言写UART无输出,求问题排查

问题排查与解决

1. 链接脚本的核心错误

你的链接脚本中.text段仅指定包含hello.o(.text.bios),但C编译器生成的_start函数实际位于普通.text段(而非.text.bios),这会导致链接后的可执行文件中,代码未被正确放入指定内存区域,QEMU加载后无法执行到你的逻辑。

修改链接脚本,确保包含所有必要的代码和数据段:

ENTRY(_start)

MEMORY {
  dram_space (rwx) : ORIGIN = 0x80000000, LENGTH = 1024K
}

SECTIONS {
  .text : {
    *(.text)
    *(.text.*)
  } > dram_space

  .rodata : {
    *(.rodata)
    *(.rodata.*)
  } > dram_space

  .data : {
    *(.data)
    *(.data.*)
  } > dram_space

  .bss : {
    *(.bss)
    *(.bss.*)
  } > dram_space
}

注:将内存长度从1024改为1024K,避免代码和字符串空间不足。

2. 编译命令优化与修正

当前编译步骤冗余且缺少裸机环境必要的编译选项,直接用gcc生成目标文件更可靠:

# 直接编译为目标文件,添加裸机编译参数
riscv64-linux-gnu-gcc -march=rv64i -mabi=lp64 -ffreestanding -nostdlib -c hello.c -o hello.o
  • -ffreestanding:告知编译器当前是无操作系统的独立环境
  • -nostdlib:不链接标准库,避免引入不必要的依赖

链接命令简化为:

riscv64-linux-gnu-ld -T linker.ld -m elf64lriscv -static -nostdlib -o hello hello.o

移除--no-dynamic-linker和-s(-s会剥离符号,不利于调试)。

3. UART访问逻辑验证

你指定的UART地址0x10000000是正确的(QEMU virt平台UART0基址),且用volatile char*确保编译器不会优化写入操作,这部分逻辑没问题。

4. 调试建议

若修改后仍无输出,可通过QEMU调试确认代码是否执行:

# 启动QEMU并等待调试连接
qemu-system-riscv64 -machine virt -bios hello -s -S

打开另一个终端用gdb连接:

riscv64-linux-gnu-gdb hello
(gdb) target remote :1234
(gdb) break _start
(gdb) continue

检查是否能命中_start断点,确认代码是否被正确加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:40:56