QEMU loader加载值到内存异常 读取返回0xffffffff
问题根因
你配置的loader加载地址0x14680000不在aarch64 virt机器的普通RAM地址范围内,属于板载MMIO外设预留地址区间。
aarch64 virt机器默认物理地址布局规则如下:
- 0x00000000 ~ 0x3FFFFFFF(共1GB):MMIO外设寄存器区间,映射GIC、UART、virtio等所有板载外设的寄存器,访问该区间内未被外设实现的地址时,硬件默认返回全1值,也就是你读到的
0xffffffff,该区间不支持普通内存的随机读写 - 0x40000000 起始:普通RAM区域,你配置了
-m 3G,因此有效可读写RAM范围为0x40000000 ~ 0xFFFFFFFF
你将loader写入地址设在了326MB位置的MMIO区间,自然无法读到预期写入的常量值。
地址空间验证方法
可以通过两种方式确认合法内存范围:
- 启动QEMU后按
Ctrl+A C组合键进入QEMU内置monitor,执行info mtree命令即可打印全量物理地址空间映射,标记为RAM的区间就是可用于加载数据、代码的合法内存区域 - 启动QEMU时追加
-d guest_errors参数,后续如果触发非法地址访问,QEMU会直接在终端打印对应错误日志,方便定位问题
修复方案
将loader设备的加载地址修改到合法RAM区间内即可,比如选择RAM偏移100MB位置0x44680000(避开内核、设备树等默认加载的低RAM区域),修改后的启动命令对应配置行如下:
-device loader,addr=0x44680000,data=0xdeadbeef,data-len=0x4 \
重新启动QEMU后再通过GDB连接读取对应地址,即可拿到正确的0xdeadbeef值。
补充说明:你之前测试文件加载功能异常,大概率也是同样的地址配置错误导致,将加载地址改到合法RAM区间后,loader设备的file=参数加载功能即可正常工作。如果开启secure=true配置后出现权限类异常,可以先关闭安全扩展完成基础功能验证,再逐步加配置调试安全态相关逻辑。
内容的提问来源于stack exchange,提问作者Icarus_Incarnate
相关产品推荐
相关产品推荐

