Qemu中如何正确使用别名内存
How to properly use alias memory in Qemu
我正在尝试在 qemu 中创建一个内存别名,但它不起作用。
我的 cortex-m3 二进制文件被link编辑到这些地址:
FLASH: 0x70010000, size 0x70000
VECTOR TABLE: 0x10000000, size 0x800
RAM: 0x10000800, size 0x20000
并且由于 cortex-m3 期望向量 table 出现在地址 0,我认为在地址 0 处创建一个别名区域就足够了,该别名区域引用地址 0x10000000 处的 table :
MemoryRegion* systemMemory = get_system_memory();
MemoryRegion *flash = g_new(MemoryRegion, 1);
MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *ram_vectors = g_new(MemoryRegion, 1);
MemoryRegion *vector_alias = g_new(MemoryRegion, 1);
memory_region_init_ram(flash, NULL, "flash", 0x70000, &error_fatal);
memory_region_add_subregion(systemMemory, 0x70010000, flash);
memory_region_init_ram(ram_vectors, NULL, "ram.vectors", 0x800, &error_fatal);
memory_region_add_subregion(systemMemory, 0x10000000, ram_vectors);
memory_region_init_alias(vector_alias, NULL, "flash.vectors", ram_vectors, 0, 0x800);
memory_region_add_subregion(systemMemory, 0, vector_alias);
memory_region_init_ram(ram, NULL, "ram", 0x20000, &error_fatal);
memory_region_add_subregion(systemMemory, 0x10000800, ram);
但 Qemu 停止并显示错误消息:
qemu-system-arm: Trying to execute code outside RAM or ROM at 0x98700306
我没有看到 Qemu 中的内存设置有什么问题。
编辑:
如果我 link 向量 table 到地址 0(并且还更改了 qemu 中的内存区域设置),那么来自 qemu 的跟踪如下所示:
arm-softmmu/qemu-system-arm -M mymachine -cpu cortex-m3 -kernel kernel.elf -
monitor none -chardev udp,id=char0,port=4444,localport=4445 -chardev
udp,id=char1,port=4446,localport=4447 -serial chardev:char0 -serial chardev:char1 -semihosting -nographic -d exec
Trace 0x7f1976abe0c0 [0: 000008a0] _start
Stopped execution of TB chain before 0x7f1976abe0c0 [000008a0] _start
Trace 0x7f1976abe0c0 [0: 000008a0] _start
Linking TBs 0x7f1976abe0c0 [000008a0] index 1 -> 0x7f1976abe340 [000008ae]
Trace 0x7f1976abe340 [0: 000008ae] _start
Linking TBs 0x7f1976abe340 [000008ae] index 0 -> 0x7f1976abe4c0 [000008aa]
Trace 0x7f1976abe4c0 [0: 000008aa] _start
Linking TBs 0x7f1976abe4c0 [000008aa] index 1 -> 0x7f1976abe340 [000008ae]
Trace 0x7f1976abe340 [0: 000008ae] _start
Linking TBs 0x7f1976abe4c0 [000008aa] index 0 -> 0x7f1976abe600 [000008b4]
Trace 0x7f1976abe600 [0: 000008b4] _start
Linking TBs 0x7f1976abe600 [000008b4] index 1 -> 0x7f1976abe800 [000008be]
Trace 0x7f1976abe800 [0: 000008be] _start
Linking TBs 0x7f1976abe800 [000008be] index 0 -> 0x7f1976abe980 [000008ba]
Trace 0x7f1976abe980 [0: 000008ba] _start
Linking TBs 0x7f1976abe980 [000008ba] index 1 -> 0x7f1976abe800 [000008be]
Trace 0x7f1976abe800 [0: 000008be] _start
Linking TBs 0x7f1976abe980 [000008ba] index 0 -> 0x7f1976abeac0 [000008c4]
Trace 0x7f1976abeac0 [0: 000008c4] _start
Trace 0x7f1976abebc0 [0: 00003d60] main
复位跳转地址正确获取,从8a0(_start)开始执行
但是如果我 link 向量 table 到 RAM 的起始地址 0x10000000,并将其别名为 0x0,qemu 不会获取正确的跳转地址:
Trace 0x7ff0ad83b0c0 [0: 00000000] <<<<-----THIS SHOULD BE 700100a0
Stopped execution of TB chain before 0x7ff0ad83b0c0 [00000000]
Trace 0x7ff0ad83b0c0 [0: 00000000]
Trace 0x7ff0ad83b1c0 [0: 7003a5d0] MemFaultHandler
Stopped execution of TB chain before 0x7ff0ad83b1c0 [7003a5d0] MemFaultHandler
Trace 0x7ff0ad83b1c0 [0: 7003a5d0] MemFaultHandler
Linking TBs 0x7ff0ad83b1c0 [7003a5d0] index 0 -> 0x7ff0ad83b5c0 [7003a5f0]
Trace 0x7ff0ad83b5c0 [0: 7003a5f0] MemFaultHandler
这里有趣的部分是它跳转到 MemFaultHandler,并且该跳转地址是从向量 table 中正确获取的,但不是起始地址!
你应该给我们你的 QEMU 命令行 -- QEMU 中许多奇怪的客人行为可以追溯到 "command line is incorrect"。
0x800 是小得令人难以置信的 RAM -- 不到 1K。你没有说你试图建模什么硬件,但我怀疑它有 0x800 字节的 RAM——它可能有一个更大的区域你应该建模。我提到这个是因为 QEMU 在从大小小于 1K 的 RAM 块执行时有问题,所以你可能会 运行 到那个。与其在 0x10000000 和 0x100000800 处有两个彼此相邻的 RAM 区域,您应该只有一个 RAM 区域,无论 RAM 大小如何,从 0x10000000 开始。
我还建议使用 QEMU 的 -d 调试日志记录来跟踪程序尝试执行的位置。这可以捕获很多奇怪的 "didn't do what I expected at startup and crashed" 错误。这应该告诉您为什么执行结束于 0x98700306。
我正在尝试在 qemu 中创建一个内存别名,但它不起作用。
我的 cortex-m3 二进制文件被link编辑到这些地址:
FLASH: 0x70010000, size 0x70000
VECTOR TABLE: 0x10000000, size 0x800
RAM: 0x10000800, size 0x20000
并且由于 cortex-m3 期望向量 table 出现在地址 0,我认为在地址 0 处创建一个别名区域就足够了,该别名区域引用地址 0x10000000 处的 table :
MemoryRegion* systemMemory = get_system_memory();
MemoryRegion *flash = g_new(MemoryRegion, 1);
MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *ram_vectors = g_new(MemoryRegion, 1);
MemoryRegion *vector_alias = g_new(MemoryRegion, 1);
memory_region_init_ram(flash, NULL, "flash", 0x70000, &error_fatal);
memory_region_add_subregion(systemMemory, 0x70010000, flash);
memory_region_init_ram(ram_vectors, NULL, "ram.vectors", 0x800, &error_fatal);
memory_region_add_subregion(systemMemory, 0x10000000, ram_vectors);
memory_region_init_alias(vector_alias, NULL, "flash.vectors", ram_vectors, 0, 0x800);
memory_region_add_subregion(systemMemory, 0, vector_alias);
memory_region_init_ram(ram, NULL, "ram", 0x20000, &error_fatal);
memory_region_add_subregion(systemMemory, 0x10000800, ram);
但 Qemu 停止并显示错误消息:
qemu-system-arm: Trying to execute code outside RAM or ROM at 0x98700306
我没有看到 Qemu 中的内存设置有什么问题。
编辑: 如果我 link 向量 table 到地址 0(并且还更改了 qemu 中的内存区域设置),那么来自 qemu 的跟踪如下所示:
arm-softmmu/qemu-system-arm -M mymachine -cpu cortex-m3 -kernel kernel.elf -
monitor none -chardev udp,id=char0,port=4444,localport=4445 -chardev
udp,id=char1,port=4446,localport=4447 -serial chardev:char0 -serial chardev:char1 -semihosting -nographic -d exec
Trace 0x7f1976abe0c0 [0: 000008a0] _start
Stopped execution of TB chain before 0x7f1976abe0c0 [000008a0] _start
Trace 0x7f1976abe0c0 [0: 000008a0] _start
Linking TBs 0x7f1976abe0c0 [000008a0] index 1 -> 0x7f1976abe340 [000008ae]
Trace 0x7f1976abe340 [0: 000008ae] _start
Linking TBs 0x7f1976abe340 [000008ae] index 0 -> 0x7f1976abe4c0 [000008aa]
Trace 0x7f1976abe4c0 [0: 000008aa] _start
Linking TBs 0x7f1976abe4c0 [000008aa] index 1 -> 0x7f1976abe340 [000008ae]
Trace 0x7f1976abe340 [0: 000008ae] _start
Linking TBs 0x7f1976abe4c0 [000008aa] index 0 -> 0x7f1976abe600 [000008b4]
Trace 0x7f1976abe600 [0: 000008b4] _start
Linking TBs 0x7f1976abe600 [000008b4] index 1 -> 0x7f1976abe800 [000008be]
Trace 0x7f1976abe800 [0: 000008be] _start
Linking TBs 0x7f1976abe800 [000008be] index 0 -> 0x7f1976abe980 [000008ba]
Trace 0x7f1976abe980 [0: 000008ba] _start
Linking TBs 0x7f1976abe980 [000008ba] index 1 -> 0x7f1976abe800 [000008be]
Trace 0x7f1976abe800 [0: 000008be] _start
Linking TBs 0x7f1976abe980 [000008ba] index 0 -> 0x7f1976abeac0 [000008c4]
Trace 0x7f1976abeac0 [0: 000008c4] _start
Trace 0x7f1976abebc0 [0: 00003d60] main
复位跳转地址正确获取,从8a0(_start)开始执行
但是如果我 link 向量 table 到 RAM 的起始地址 0x10000000,并将其别名为 0x0,qemu 不会获取正确的跳转地址:
Trace 0x7ff0ad83b0c0 [0: 00000000] <<<<-----THIS SHOULD BE 700100a0
Stopped execution of TB chain before 0x7ff0ad83b0c0 [00000000]
Trace 0x7ff0ad83b0c0 [0: 00000000]
Trace 0x7ff0ad83b1c0 [0: 7003a5d0] MemFaultHandler
Stopped execution of TB chain before 0x7ff0ad83b1c0 [7003a5d0] MemFaultHandler
Trace 0x7ff0ad83b1c0 [0: 7003a5d0] MemFaultHandler
Linking TBs 0x7ff0ad83b1c0 [7003a5d0] index 0 -> 0x7ff0ad83b5c0 [7003a5f0]
Trace 0x7ff0ad83b5c0 [0: 7003a5f0] MemFaultHandler
这里有趣的部分是它跳转到 MemFaultHandler,并且该跳转地址是从向量 table 中正确获取的,但不是起始地址!
你应该给我们你的 QEMU 命令行 -- QEMU 中许多奇怪的客人行为可以追溯到 "command line is incorrect"。
0x800 是小得令人难以置信的 RAM -- 不到 1K。你没有说你试图建模什么硬件,但我怀疑它有 0x800 字节的 RAM——它可能有一个更大的区域你应该建模。我提到这个是因为 QEMU 在从大小小于 1K 的 RAM 块执行时有问题,所以你可能会 运行 到那个。与其在 0x10000000 和 0x100000800 处有两个彼此相邻的 RAM 区域,您应该只有一个 RAM 区域,无论 RAM 大小如何,从 0x10000000 开始。
我还建议使用 QEMU 的 -d 调试日志记录来跟踪程序尝试执行的位置。这可以捕获很多奇怪的 "didn't do what I expected at startup and crashed" 错误。这应该告诉您为什么执行结束于 0x98700306。