All tools
Linker script builder.
Pick a preset or define memory regions, pick where the stack and vector table live, and get a completelinker.ld you can drop into a GCC build — with .isr_vector, .data in flash → RAM, and proper C++ ctor arrays.
Preset
Memory regions
total 640K
KB
KB
Layout
Generated linker.ld
/* Linker script generated by armhub.dev linker-script tool
* CPU: cortex-m4
* Stack region: RAM (4K)
* Heap size: 2K
* Vector table region: FLASH
*/
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* Required amounts of heap and stack */
_Min_Heap_Size = 0x800; /* 2 KiB */
_Min_Stack_Size = 0x1000; /* 4 KiB */
MEMORY
{
FLASH (rx ) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS
{
/* --- Vector table + code + read-only data --- */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7) /* ARM/Thumb interworking veneers */
*(.glue_7t)
*(.eh_frame)
/* C++ static constructors */
. = ALIGN(4);
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
__preinit_array_start = .;
KEEP(*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
__init_array_end = .;
. = ALIGN(4);
__fini_array_start = .;
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
__fini_array_end = .;
. = ALIGN(4);
_etext = .;
} >FLASH
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
/* --- Initialized data: load address in flash, run address in RAM --- */
_sidata = LOADADDR(.data);
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
*(.RamFunc) /* code that runs from RAM */
*(.RamFunc*)
. = ALIGN(4);
_edata = .;
} >RAM AT> FLASH
/* --- Zero-initialized BSS --- */
.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
/* --- User heap & stack: keep them in the stack region, fail at link if too small --- */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
How to use
- Save as
linker.ldin your project. - Pass it to GCC with
-T linker.ld. - In your startup file, set
_estackas the initial SP in the vector table — it's defined here as the top of the stack region. - Your reset handler must zero
.bss(from_sbssto_ebss) and copy.datafrom_sidatato_sdata..._edata.
Stack ends at top of RAM — grows down toward
_end.