2026-09-08
The asker is working on a Cortex-M7 firmware project and needs to introduce a brand-new output section — .new_section — that must live at the very beginning of internal RAM. The existing linker script already places .relocate, .bss, and the stack in RAM, all driven by symbols like _srelocate, _erelocate, and _sstack that the C runtime uses during startup to copy initialised data from flash and zero out BSS.
What makes this interesting is that a linker script is not just a layout description — it is a contract with the startup code. Naively prepending a new section changes the addresses that _srelocate and _sbss resolve to, which can silently break the boot process: the copy loop will write to the wrong place, or BSS clearing will trample your new section. On top of that, the Cortex-M7 has tight rules for the vector table (must be at the start of RAM if remapped) and for MPU-protected regions (base must be aligned to region size).
Direction toward a solution:
.new_section as the first output section in the RAM region, with an explicit ALIGN matching its intended MPU alignment. Something like:
.new_section (NOLOAD) :
{
. = ALIGN(32);
_snew_section = .;
KEEP(*(.new_section .new_section.*))
. = ALIGN(4);
_enew_section = .;
} > ramNOLOAD if the section only needs runtime storage (no flash image). Drop it if you want initialised data copied from flash — but then you also need a load-address (AT>) and copy loop.__attribute__((section(".new_section"))) in C, so nothing accidentally falls into it._srelocate/_sbss/_estack symbols anchored to the sections they describe — do not hoist them above your new section, or startup will misbehave.Gotchas:
SCB->VTOR), pushing it down by sizeof(.new_section) means VTOR must be updated too — and it has its own alignment constraint (next power of two ≥ table size, minimum 128 bytes).. = ALIGN(size); . += size; tricks or a . = ORIGIN(ram) + poweroftwo; guard.