I am trying to emulate STM32F407XX controller with cortex M4 processor on QEMU. I wrote the .ld file as below:
ENTRY(_Reset)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
PERIPHERALS(rw) : ORIGIN = 0x40000000, LENGTH = 128K
}
SECTIONS
{
.startup . : { stm32.o(.text) } >FLASH
.text : { *(.text) }
.data : { *(.data) } >RAM AT> FLASH
.bss : { *(.bss COMMON) } >RAM
. = ALIGN(4);
. = . + 0x400; /* required amount of stack */
stack_top = 0x20020000;
}
When i generate the .elf file and run the code, I get the fault
Qemu: fatal: Lockup: cant escalate 3 to Hardfault (Current Priority -1) error.
Aborted (Core Dumped)
I feel its a memory problem. What am I doing wrong? I have allocated the flash, RAM memories according the reference manual requirements for STM32F407.
why does this error come in the first place & How can I resolve this error? Thanks.
Placing the vector table at the correct place solved the issue. I followed all the instructions by @peter Maydell in the comments above. I am adding them here.
You can turn on some of the debug logging options of QEMU with -d ('in_asm,int,exec,cpu,guest_errors,unimp' are probably a good set to start with), which will tell you what your guest code is doing. I would start by checking that your ELF file has a vector table in it at the place where QEMU expects to find it. Otherwise QEMU will hard fault immediately out of reset (which is what the hardware does).
The core dump is expected: QEMU goes into lockup, but we don't emulate lockup correctly (strictly speaking QEMU should just sit there doing nothing like the real hardware does), so we print a register dump and abort(). As I said in my previous comment, your problem is almost certainly that your binary doesn't have a vector table.
The main thing you must have in your vector table is the entries for the initial PC and stack pointer. The interrupt and exception entries are worth putting in but will only be needed if there is an interrupt or exception. If you put in debugging handlers for the other faults you'll at least know when you get a fault due to a bug in the rest of your program, though
You need to reset your ROM after your kernel loading in your machine (after armv7m_load_kernel
call). You can use for example:
rom_check_and_register_reset();
qemu_devices_reset();
CPU should start on Reset Handler.
Additional information for anyone like me that comes across this trying to fix a qemu hardfault: I got the same hardfault due to an unimplemented instruction.
This happened because I compiled the code with -mcpu=cortex-m4
but ran qemu with -cpu cortex-m3
The tricky thing about this is that it works for most of the code because gcc most often doesn't use one of the "m4-only-instructions" (even depending on the optimization level - it worked with -O1
but failed with -O2
)...
User contributions licensed under CC BY-SA 3.0