QEMU-system-riscv64中OpenSBI与内核地址重叠的解决方法咨询
解决OpenSBI DYNAMIC与内核地址重叠问题
问题根源
QEMU默认将OpenSBI fw_dynamic固件加载到0x80000000起始地址,而你使用的bbl(包含Linux内核的bootloader)默认也会被加载到该地址区间,导致内存重叠报错。
可行解决方案
方案1:修改bbl编译配置,指定加载地址为0x80200000
bbl作为riscv-pk的组件,编译时可通过配置参数指定payload(即内核)的加载地址:
- 进入riscv-pk源码目录,重新执行configure命令,添加
--with-payload-loadaddr=0x80200000参数:
../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu --with-payload=../linux/arch/riscv/boot/Image --with-payload-loadaddr=0x80200000
- 重新编译并安装:
make clean && make && make install
编译完成后,新生成的bbl会将内核加载到0x80200000,与OpenSBI的地址区间无重叠,直接使用原启动命令即可正常运行。
方案2:跳过bbl,用OpenSBI直接引导Linux内核
bbl属于较旧的RISC-V bootloader,OpenSBI fw_dynamic支持直接引导Linux内核,无需依赖bbl:
- 确保你的Linux内核已编译生成
Image(未压缩镜像)或vmlinuz(压缩镜像); - 修改启动命令,替换
-kernel build/riscv-pk/bbl为直接指定内核镜像,并显式指定OpenSBI固件路径:
cmd="${QEMU_SYSTEM_BIN} -nographic -machine virt -m 128M \ -bios /usr/bin/../share/qemu/opensbi-riscv64-generic-fw_dynamic.bin \ -kernel build/linux/arch/riscv/boot/Image \ -append \"root=/dev/vda1 ro console=ttyS0\" \ -drive file=riscv64-rootfs.bin,format=raw,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -netdev ${QEMU_NETDEV},id=net0 \ -device virtio-net-device,netdev=net0 \ "
Linux内核RISC-V版本默认加载地址为0x80200000,与OpenSBI的地址区间不重叠,可直接避免冲突。
方案3:手动指定bbl加载地址(不推荐,需配合编译修改)
若必须保留bbl,可通过QEMU的loader设备手动指定加载地址,但需先修改bbl的链接地址(否则运行时会因地址不匹配崩溃):
- 先按方案1重新编译bbl,修改其链接地址为
0x80200000; - 将bbl转换为二进制镜像:
riscv64-unknown-linux-gnu-objcopy -O binary build/riscv-pk/bbl bbl.bin
- 修改启动命令,使用
loader设备加载二进制镜像到指定地址:
cmd="${QEMU_SYSTEM_BIN} -nographic -machine virt -m 128M \ -bios /usr/bin/../share/qemu/opensbi-riscv64-generic-fw_dynamic.bin \ -device loader,file=bbl.bin,addr=0x80200000 \ -append \"root=/dev/vda1 ro console=ttyS0\" \ -drive file=riscv64-rootfs.bin,format=raw,id=hd0 \ -device virtio-blk-device,drive=hd0 \ -netdev ${QEMU_NETDEV},id=net0 \ -device virtio-net-device,netdev=net0 \ "
内容的提问来源于stack exchange,提问作者Thysrael
相关产品推荐
相关产品推荐

