Walk me through a linker script — what are the key sections and directives?
A linker script (.ld file) tells the linker how to map compiled object file sections into physical memory regions. It has two main blocks: MEMORY and SECTIONS. The MEMORY block defines the available memory regions with their start addresses, sizes, and attributes. For a typical STM32F407, this looks like FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K and RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K. The rx and rwx flags specify read/execute and read/write/execute permissions respectively. Additional regions might include CCM RAM, external SDRAM, or backup SRAM.
The SECTIONS block maps each input section to a memory region and defines the layout order. The .isr_vector section comes first (placed at the start of FLASH with KEEP() to prevent garbage collection). Next, .text holds all code and read-only data (const variables, string literals). Then .rodata for additional read-only data. The .data section is more complex because it has two addresses: a VMA (Virtual Memory Address) in RAM where the variables live at runtime, specified with > RAM, and an LMA (Load Memory Address) in Flash where the initial values are stored, specified with AT> FLASH. The linker exports symbols at the boundaries: _sidata (Flash source), _sdata (RAM start), _edata (RAM end). The .bss section is placed in RAM with _sbss and _ebss symbols. Finally, ._user_heap_stack typically reserves space for the heap (growing up) and stack (growing down) with PROVIDE symbols for _end (heap start) and _estack (initial stack pointer, usually the top of RAM).
Key directives to know: KEEP() prevents sections from being discarded by --gc-sections (used for the vector table and interrupt handlers that are referenced by hardware, not code). ALIGN() ensures sections start on word boundaries (critical for DMA buffers and memory-mapped peripherals). PROVIDE() creates symbols only if they are not already defined elsewhere, allowing user code to override default values. . (the location counter) tracks the current address during layout. Understanding VMA vs LMA is the most critical concept — it is what enables initialized data to be stored in Flash but used from RAM, which is the foundation of the .data copy mechanism.
Source: Boot & Startup Q&A
