代码之家  ›  专栏  ›  技术社区  ›  user2479653

如何在Qemu中正确使用别名内存

  •  1
  • user2479653  · 技术社区  · 7 年前

    我试图在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开始(\u 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,跳转地址是从向量表中正确获取的,但不是起始地址!

    1 回复  |  直到 7 年前
        1
  •  0
  •   Peter Maydell    7 年前

    您应该给我们您的QEMU命令行——QEMU中来宾的许多奇怪行为可以追溯到“命令行不正确”。

    0x800是一个难以置信的小内存量——小于1K。你没有说你想建模什么硬件,但我怀疑它有0x800字节的RAM——它可能有一个更大的区域,你应该建模。我提到这一点是因为QEMU在从小于1K的RAM块执行时存在问题,所以您可能会遇到这种情况。与其在0x10000000和0x10000800处有两个相邻的RAM区域,不如从0x10000000处开始,只拥有一个RAM大小不限的RAM区域。

    我还建议使用QEMU的-d调试日志记录来跟踪程序试图从何处执行。这可能会捕捉到很多奇怪的“在启动时没有做到我所期望的,然后崩溃了”bug。这应该告诉您为什么执行以0x98700306结束。