In this lesson, you will learn how to correlate your startup assembly code with your linker map file to pinpoint exactly why your system crashes before reaching main().
When a processor powers on, it executes a reset vector that points to your startup assembly (often startup.s). This code performs critical tasks like initializing the stack pointer and copying data from Flash to RAM. If your system hangs or triggers a hard fault during this phase, the error is often due to an address mismatch or an alignment fault.
The Debugging Workflow
When you encounter a startup failure, your first tool should be the Linker Map File. The map file acts as a definitive record of where every symbol and section was placed during the link-time resolution process.
Suppose your assembly code attempts to load the stack pointer address from a symbol defined in your linker script:
/* Startup Assembly */
ldr r0, =__stack_top
mov sp, r0
If the hardware faults immediately, your first step is to open the .map file and search for __stack_top. You might find:
.stack 0x20000800 0x400
0x20000c00 __stack_top = .
Correlating Assembly and Map Files
Check if the address in the map file is 8-byte aligned (as required by many ARM Cortex-M architectures). If your linker script calculation for __stack_top resulted in an odd address, the MOV SP, R0 instruction will trigger a UsageFault immediately.
Furthermore, check the Load Address vs. Virtual Address. If your data copy routine (e.g., memcpy for .data sections) fails, search the map file for the start of the .data section. Compare the LOAD address (where the data lives in Flash) and the VIRTUAL address (where the CPU expects it in RAM). If your assembly loop uses an incorrect pointer range, the map file will show you if your code is attempting to copy data to a region that hasn't been properly mapped or is protected by the MPU.
By verifying that the symbols your assembly code references actually resolve to the memory addresses you expect, you eliminate the guesswork in debugging initialization crashes.
Key Takeaway: Use the linker map file to verify that the absolute memory addresses loaded into registers during startup align with your hardware’s memory map constraints and alignment requirements.