如何为qemu-system-arm模拟器指定运行自定义bootloader
问题根因
你遇到的问题来自核心的平台逻辑差异和启动参数错误:
- 你添加的
0x55, 0xaa扇区签名是x86架构BIOS MBR启动的专属校验规则:x86 BIOS启动时会自动读取启动盘第一个扇区,校验末尾两字节为0x55aa后将其加载到0x7c00地址跳转执行。ARM架构没有统一的MBR启动规范,不同板卡/模拟平台的启动校验、加载地址逻辑完全不同,这个字段对ARM平台启动无任何作用。 - QEMU不同架构的默认参数逻辑不通用:你之前在x86下直接把bin文件作为位置参数传给
qemu-system-i386能运行,是因为x86默认的PC机器模型会自动把未指定类型的位置参数文件识别为软盘镜像,走MBR加载流程。但qemu-system-arm的virt机器模型没有这套默认逻辑,未显式指定启动镜像时,QEMU会默认加载内置的UEFI固件/演示程序,也就是你看到的自带交互界面,根本没有加载你编写的二进制文件。 - ARM
virt平台上电后,CPU默认从物理地址0x0开始取指执行,不存在x86那种固定加载到0x7c00的MBR规则。
正确操作步骤
- (可选)精简汇编代码
你可以去掉x86专属的填充和签名字段,ARM启动不需要这些内容,最小可运行代码如下:
.global _start _start: B .
保留原来的填充和签名也不会影响运行,只是完全无效。
2. 原有汇编、二进制生成命令无需修改,正常执行即可生成可运行的裸二进制:
arm-linux-gnu-as -mcpu=cortex-a15 -o dist/output.o bootsect.s arm-linux-gnu-objcopy -O binary -o dist/output.bin dist/output.o
- 修正QEMU启动参数,使用
-kernel参数显式指定你的裸二进制文件,QEMU会自动将其加载到0x0起始地址直接运行:
qemu-system-arm -M virt -cpu cortex-a15 -nographic -kernel dist/output.bin
参数说明:
-kernel:指定要直接加载运行的裸二进制/内核镜像,是virt平台运行裸机程序最简单的方式-nographic:关闭图形界面,直接将串口输出绑定到当前终端,你这个示例是死循环,执行后终端会无响应,说明你的代码已经正常跑起来了,按Ctrl+A再按X即可退出QEMU。
补充说明
如果你想模拟类似x86从块设备加载启动扇区的流程,需要额外创建磁盘镜像、指定块设备参数、关闭默认固件加载,对于编写最基础的裸机bootloader来说,直接用-kernel参数加载是最简便、适配virt平台启动逻辑的方案。
内容的提问来源于stack exchange,提问作者Alvan Rahimli
相关产品推荐
相关产品推荐

