我正在尝试在qemu中创建一个内存别名,但它不起作用。
我的cortex-m3二进制文件链接到这些地址:
FLASH: 0x70010000, size 0x70000
VECTOR TABLE: 0x10000000, size 0x800
RAM: 0x10000800, size 0x20000
由于cortex-m3期望向量表出现在地址0,我认为在地址0处创建一个引用地址为0x10000000的表的别名区域就足够了:
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内存设置有什么问题。
修改 如果我将向量表链接到地址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)
开始执行但是,如果我将向量表链接到0x10000000的RAM开头,并将其别名为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,并且从向量表中正确获取跳转地址,但不是起始地址!
答案 0 :(得分:0)
你应该给我们你的QEMU命令行 - QEMU中很多奇怪的客户行为都可以追溯到“命令行不正确”。
0x800是一个令人难以置信的少量RAM - 小于1K。你没有说你想要建模的硬件,但我怀疑它有0x800字节的RAM - 它可能有一个你应该建模的更大的区域。我之所以提到这一点,是因为QEMU在从小于1K的RAM块执行时遇到问题,所以你可能会遇到这种情况。在0x10000000和0x100000800处没有两个彼此相邻的RAM区域,您应该只有一个RAM的区域,其大小与RAM相同,从0x10000000开始。
我还建议使用QEMU的-d调试日志来跟踪程序尝试执行的位置。这可以捕获很多奇怪的“没有做我在启动时预期和崩溃”的错误。这应该告诉你为什么执行结束于0x98700306。