A linker script defines symbols that mark the boundaries of memory regions and sections, which the startup code and runtime rely on. The standard set for initializing memory: _sidata is the flash load address of the .data initial values (the copy source), _sdata and _edata bracket the .data run range in RAM (the copy destination), and _sbss and _ebss bracket the .bss range that must be zeroed. The startup/reset code references these as external symbols and loops over them: copy from _sidata into _sdata.._edata, then zero _sbss.._ebss. The script also typically defines _estack (often ORIGIN(RAM) + LENGTH(RAM), the top of RAM) which becomes the initial stack pointer in the first vector-table entry, and sets ENTRY(Reset_Handler) to name the program's entry symbol. There may be additional symbols for heap boundaries, end-of-text markers, or custom regions. The crucial point is that the symbol names in the script must exactly match what the startup code expects, they're a contract between the two, because a mismatch means the startup loop copies or zeroes the wrong address range, producing partially or incorrectly initialized memory that's very hard to debug. So the linker script and the startup file are co-designed around these symbols.
Debugging & Toolchain · Interview question
What symbols does a linker script provide, and who uses them?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
Linker Scripts & Memory Sections
Telling the linker the chip's memory map: MEMORY and SECTIONS place .text in flash and .data/.bss in RAM, and the VMA-vs-LMA split is why startup code must copy initialized data.