【发布时间】:2019-07-24 13:18:10
【问题描述】:
我正在为一个特定的评估板建模,它有一个 leon3 处理器和多个映射到特定地址的 MRAM 组。我的目标是使用我的引导加载程序 ELF 启动 qemu-system-sparc,然后跳转到 MRAM 库的基地址以开始在其中执行裸机程序。为此,我已经能够成功运行我的引导加载程序并跳转到第一条指令,但是 QEMU 立即停止并退出而没有报告任何错误/陷阱。我还可以通过将 ELF 格式的裸机程序作为内核传递给 qemu-system-sparc 来单独运行裸机程序。
短版:是否有规范的方法来设置设备,以便可以直接从中执行代码?编译该代码以使其正确执行时,我需要采取哪些步骤?
我将 MRAM 建模为具有 MemoryRegion 的设备,以及适当的读写操作,以在我的程序中公开堆分配的数组。在我的板代码(qemu/hw/sparc/leon3.c 的修改版本)中,对 MRAM 地址的写入被映射到设备的 MemoryRegion。使用 printfs,我以未实现设备 (qemu/hw/misc/unimp.c) 的样式报告读取和写入,并且我已验证我正在正确读取和写入设备。
很遗憾,这对于在设备上运行代码不起作用。在引导加载程序跳转到我设备的基地址后,我可以立即看到读取内容,但读取的指令实际上并没有做任何事情。引导加载程序使用 void 函数指针,该指针与 MRAM 设备的地址绑定以引发跳转。
我尝试的另一种方法是从地址 0 开始为我的设备创建一个别名;我想也许我的二进制文件的所有地址都设置为相对于零,因此通过将地址 [0, MRAM_SIZE) 的写入作为别名映射到我的设备基地址,代码最终将读取设备 MemoryRegion 中的相应指令。
这种方法在 memory.c 中的断言失败:
static void memory_region_add_subregion_common(MemoryRegion *mr,
hwaddr offsset,
MemoryRegion *subregion)
{
assert(!subregion->container);
subregion->container = mr;
subregion->addr = offset;
memory_region_update_container_subregions(subregion);
}
我需要做什么来强制 QEMU 在我的 MRAM 设备中执行代码?我需要生成具有绝对地址的二进制文件吗?
【问题讨论】: