qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Trying to execute code outside RAM or ROM at 0x08000230


From: Liviu Ionescu
Subject: [Qemu-devel] Trying to execute code outside RAM or ROM at 0x08000230
Date: Sat, 6 Jun 2015 22:01:29 +0300

while working on the STM32 emulation, I noticed a problem related to the 
specific memory layout of STM32 devices.

these devices have the FLASH region at 0x08000000 instead of 0x00000000, and 
since the specs require the presence of the reset vector at 0x0, there is an 
internal alias of the entire region 0x08000000 at 0x00000000.

however programming the flash via a jtag works only in the 0x08000000 range, 
and although possible to make the linker script to run the code at 0x0 and 
program it at 0x08000000, this is usually not done, and most STM32 applications 
are linked to run directly at 0x08000000.

unfortunately qemu is not very happy with this arrangement :-(


the STM32 initialisation code I used, similar to that used by Alistair, takes a 
reversed approach, it first creates the main flash region at 0x00000000: 

    MemoryRegion *flash_mem = g_new(MemoryRegion, 1);

    memory_region_init_ram(flash_mem, NULL, "cortexm-mem-flash", flash_size,
            &error_abort);
    vmstate_register_ram_global(flash_mem);
    memory_region_set_readonly(flash_mem, true);
    memory_region_add_subregion(system_memory, 0x00000000, flash_mem);

and then creates a memory alias at 0x08000000:

    MemoryRegion *flash_alias_mem = g_malloc(sizeof(MemoryRegion));

    memory_region_init_alias(flash_alias_mem, NULL, "stm32-mem-flash-alias",
            get_system_memory(), 0, flash_size_kb);
    memory_region_set_readonly(flash_alias_mem, true);
    memory_region_add_subregion(get_system_memory(), 0x08000000,
            flash_alias_mem);


this works fine, however it crashes when the core tries to executes the first 
instruction in the 0x08000000 region.

it crashes in cputlb.c: get_page_addr_code() since the memory region is found 
as 'unassigned':

    if (memory_region_is_unassigned(mr)) {
        CPUClass *cc = CPU_GET_CLASS(cpu);

        if (cc->do_unassigned_access) {
            cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
        } else {
            cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
                      TARGET_FMT_lx "\n", addr);
        }
    }

I tried to disable the if(), but later bad things happened... :-(


since my experience at that great depth in qemu is limited, I would appreciate 
any advice on how to proceed.


at first sight emulation follows a very complicated path required in larger ARM 
cores, but completely useless for cortex-m, since none have MMUs and TLBs.

ideally cortex-m cores should have a configuration bit to completely skip MMU 
specific processing.


thank you in advance,

Liviu









reply via email to

[Prev in Thread] Current Thread [Next in Thread]