伟明部落格

RISCV-64裸机(baremetal)编程

--发布于 2025-08-04 22:03:57

环境

Linux zwm-PC 6.6.40-amd64-desktop-hwe #23.01.00.33 SMP PREEMPT_DYNAMIC Thu Jul 25 15:29:39 CST 2024 x86_64 GNU/Linux

在进行实验之前,需安装好qemu-system-riscv64gcc-riscv64-linux-gnu

apt install qemu-system-riscv64
apt install gcc-riscv64-linux-gnu

步骤

  1. 新建源文件hello.s。QEMU将UART映射到地址0x10000000处,如果你发送一个8位数值到那个地址上,这个数值对应的字符就会显示在QEME控制台终端上。
    .global _start
    .section .text.bios

_start: addi a0, x0, 0x68
    li a1, 0x10000000
    sb a0, (a1) # 'h'

    addi a0, x0, 0x65
    sb a0, (a1) # 'e'

    addi a0, x0, 0x6C
    sb a0, (a1) # 'l'

    addi a0, x0, 0x6C
    sb a0, (a1) # 'l'

    addi a0, x0, 0x6F
    sb a0, (a1) # 'o'

loop:   j loop
  1. 新建链接脚本link.ld。地址0x80000000为QEMU执行用户提供的程序的入口地址。
MEMORY {
  dram_space (rwx) : ORIGIN = 0x80000000, LENGTH = 128
}

SECTIONS {
  .text : {
    hello.o(.text.bios)
  } > dram_space
}
  1. 新建编译脚本build.sh
# 先编译为hello.o
riscv64-linux-gnu-as -march=rv64i -mabi=lp64 -o hello.o -c hello.s
# 再链接为hello.elf
riscv64-linux-gnu-ld -T link.ld -o hello.elf hello.o
  1. 执行如下步骤
# 编译
./build.sh

# 执行
qemu-system-riscv64 -machine virt -bios hello.elf
  1. 在QEMU的视图菜单那里,选择串口(在这里是serial0),就会看到输出的hello字符串。

  1. 如果以字符界面方式启动的话,即加上-nographic选项
qemu-system-riscv64 -nographic -machine virt -bios hello.elf

退出时,需要先按Ctrl+A,松开后,再按X键,即可退出QEMU。

参考

Bare metal programming with RISC-V guide

下面是Google AI对QEMU地址0x80000000的总结

In the context of QEMU, particularly when emulating RISC-V systems, the address 0x80000000 commonly represents the start of the emulated DRAM (Dynamic Random-Access Memory).

Here's a breakdown of its significance:

  • Entry Point for Bootloaders/Kernels:

    When you boot a bare-metal program, a bootloader, or a kernel in QEMU's RISC-V virt platform, 0x80000000 is typically the address where the initial instructions are loaded and executed.

  • Default Load Address:

    If no specific load address is provided, QEMU's riscv64 virt machine will often load the initial boot code (like OpenSBI, a RISC-V Supervisor Binary Interface implementation) at 0x80000000.

  • Memory Mapping:

    This address serves as the base for the guest's physical memory in the QEMU-emulated environment. Operating systems and applications running within the guest will typically map their memory relative to this base address.

  • Linker Script Configuration:

    When building a custom kernel or bare-metal application for RISC-V on QEMU, linker scripts are often used to explicitly place the code's entry point and text/data sections at 0x80000000 to align with QEMU's default behavior.

In essence, 0x80000000 signifies a crucial starting point for software execution and memory allocation within a QEMU-emulated RISC-V system.

--更新于 2025-08-04 22:05:31