QEMU模拟riscv64架构启动冻结,求助排查与解决方法
QEMU模拟RISC-V64启动冻结问题排查与解决
问题描述
使用QEMU模拟RISC-V64架构时,启动后仅显示部分输出即冻结,无后续日志,Linux内核加载过程停滞。
执行的启动命令
qemu-system-riscv64 \ -nographic \ -machine virt \ -kernel $OUT/bbl \ -append 'root=/dev/vda ro console=ttyS0' \ -drive file=$OUT/riscv_disk,format=raw,id=hd0,if=none \ -device virtio-blk-device,drive=hd0
冻结时的输出
qemu-system-riscv64 -D ~/qemulog.txt -nographic -smp 2 -machine virt -bios none -kernel $OUT/bbl -append 'root=/dev/vda ro console=ttyS0' -drive file=$OUT/riscv_disk,format=raw,id=hd0,if=none -device virtio-blk-device,drive=hd0 hart_filter_mask saw unknown hart type: status="okay", mmu_type="riscv,sv57" hart_filter_mask saw unknown hart type: status="okay", mmu_type="riscv,sv57"
注:指定的日志文件~/qemulog.txt为空,已按照RISC-V FS Linux配置文档搭建了bbl与Linux内核环境,且已尝试更换QEMU版本、替换磁盘镜像、调整-smp参数修改CPU数量,问题仍未解决。
排查与解决建议
1. 修复SV57 MMU类型不兼容问题
输出中的hart_filter_mask saw unknown hart type提示QEMU不识别SV57页表模式,这是核心触发点:
- 在启动命令中强制指定兼容的CPU类型,比如支持SV39/SV48的RV64GC:
qemu-system-riscv64 \ -nographic \ -machine virt \ -cpu rv64gc \ -kernel $OUT/bbl \ -append 'root=/dev/vda ro console=ttyS0' \ -drive file=$OUT/riscv_disk,format=raw,id=hd0,if=none \ -device virtio-blk-device,drive=hd0 - 检查内核配置,关闭
CONFIG_RISCV_SV57选项后重新编译内核,避免生成依赖SV57的镜像。
2. 启用QEMU详细调试日志
当前-D参数未生成有效日志,改用更精准的调试参数定位停滞原因:
- 添加
-d guest_errors,unimp捕获Guest侧错误和未实现指令:qemu-system-riscv64 \ -nographic \ -machine virt \ -cpu rv64gc \ -d guest_errors,unimp \ -kernel $OUT/bbl \ -append 'root=/dev/vda ro console=ttyS0' \ -drive file=$OUT/riscv_disk,format=raw,id=hd0,if=none \ -device virtio-blk-device,drive=hd0 - 若需要更详细的跟踪,可使用
-d trace:*生成全量日志(注意日志体积较大),直接定位代码执行停滞点。
3. 验证bbl与内核兼容性
- 确认bbl版本与内核版本匹配,旧版bbl可能不支持新内核的高级特性;
- 尝试绕过bbl直接启动内核(需内核支持裸启动),命令调整为:
以此排除bbl本身的问题。qemu-system-riscv64 \ -nographic \ -machine virt \ -cpu rv64gc \ -bios none \ -kernel $OUT/vmlinux \ -append 'root=/dev/vda ro console=ttyS0' \ -drive file=$OUT/riscv_disk,format=raw,id=hd0,if=none \ -device virtio-blk-device,drive=hd0
4. 检查磁盘镜像完整性
- 使用
fdisk -l $OUT/riscv_disk验证分区表有效性,确认/dev/vda对应正确的根分区(若为分区镜像,需将启动参数改为root=/dev/vda1); - 使用
fsck.ext4 $OUT/riscv_disk(针对ext4文件系统)检查文件系统是否损坏,修复后重新尝试启动。
内容的提问来源于stack exchange,提问作者xqynl
相关产品推荐
相关产品推荐

