Linker Script Skill
Expert skill for GNU linker script generation and optimization for embedded systems. Provides deep expertise in memory layout definition, section placement, symbol management, and advanced linking scenarios.
Overview
The Linker Script skill enables comprehensive linker script development for embedded systems, supporting:
- Memory region definition for MCU targets
- Section placement and alignment configuration
- Symbol generation for bootloader/application interfaces
- Multi-image linking (bootloader + application)
- Overlay and bank switching support
- Custom section creation and management
- Fill pattern and checksum placement
- MPU-aligned region configuration
Capabilities
1. Memory Region Definition
Define memory regions based on MCU specifications:
/* Example: STM32F407 Memory Layout */
MEMORY
{
/* Flash memory regions */
FLASH_BOOT (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* Bootloader */
FLASH_APP (rx) : ORIGIN = 0x08008000, LENGTH = 480K /* Application */
FLASH_DATA (r) : ORIGIN = 0x08080000, LENGTH = 128K /* Config/OTA */
/* RAM regions */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K /* Main SRAM */
CCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K /* Core-coupled RAM */
BKPSRAM (rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Backup SRAM */
}
2. Section Placement Configuration
Configure section placement with alignment requirements:
SECTIONS
{
/* Vector table at flash start */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > FLASH_APP
/* Code sections */
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.glue_7) /* ARM/Thumb interworking */
*(.glue_7t)
*(.eh_frame)
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
_etext = .;
} > FLASH_APP
/* Read-only data */
.rodata :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} > FLASH_APP
}
3. Symbol Generation
Generate symbols for firmware interfaces:
/* Symbols for bootloader/application interface */
PROVIDE(_app_start = ORIGIN(FLASH_APP));
PROVIDE(_app_end = ORIGIN(FLASH_APP) + LENGTH(FLASH_APP));
PROVIDE(_app_checksum = _app_end - 4);
/* Stack and heap boundaries */
PROVIDE(_estack = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(_Min_Heap_Size = 0x2000); /* 8KB heap */
PROVIDE(_Min_Stack_Size = 0x1000); /* 4KB stack */
/* RAM function execution */
PROVIDE(_siramfunc = LOADADDR(.ramfunc));
PROVIDE(_sramfunc = ADDR(.ramfunc));
PROVIDE(_eramfunc = ADDR(.ramfunc) + SIZEOF(.ramfunc));
4. Multi-Image Linking
Support bootloader and application as separate images:
/* Bootloader linker script excerpt */
MEMORY
{
FLASH_BOOT (rx) : ORIGIN = 0x08000000, LENGTH = 32K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* Shared data region for boot-to-app communication */
.shared_data (NOLOAD) :
{
. = ALIGN(4);
_shared_data_start = .;
KEEP(*(.shared_data))
. = ALIGN(4);
_shared_data_end = .;
} > RAM
/* Application header location (known to bootloader) */
_app_header_addr = 0x08008000;
5. MPU Region Configuration
Define MPU-aligned memory regions:
/* MPU-aligned regions (power of 2 sizes, aligned to size) */
.mpu_region_stack (NOLOAD) :
{
. = ALIGN(1024); /* MPU minimum region size */
_mpu_stack_start = .;
. = . + 4096; /* 4KB stack region */
_mpu_stack_end = .;
} > RAM
.mpu_region_heap (NOLOAD) :
{
. = ALIGN(8192); /* 8KB aligned */
_mpu_heap_start = .;
. = . + 8192;
_mpu_heap_end = .;
} > RAM
6. Overlay Support
Configure overlay sections for memory-constrained systems:
OVERLAY : NOCROSSREFS
{
.overlay_a { *(.overlay_a) }
.overlay_b { *(.overlay_b) }
.overlay_c { *(.overlay_c) }
} > RAM AT > FLASH_APP
/* Overlay management symbols */
_overlay_a_load = LOADADDR(.overlay_a);
_overlay_b_load = LOADADDR(.overlay_b);
_overlay_c_load = LOADADDR(.overlay_c);
7. Checksum Placement
Configure checksum/CRC placement for firmware validation:
/* Reserved space for firmware checksum */
.checksum :
{
. = ALIGN(4);
_firmware_checksum = .;
LONG(0xFFFFFFFF); /* Placeholder, filled post-build */
. = ALIGN(4);
} > FLASH_APP
/* Image length for checksum calculation */
_firmware_length = _firmware_checksum - ORIGIN(FLASH_APP);
Process Integration
This skill integrates with the following processes:
| Process | Integration Point |
|---------|-------------------|
| memory-architecture-planning.js | Memory map design and validation |
| bootloader-implementation.js | Boot/app interface definition |
| bsp-development.js | BSP memory configuration |
| code-size-optimization.js | Section optimization analysis |
Workflow
1. Gather MCU Specifications
# Extract memory map from datasheet or reference manual
# Key information needed:
# - Flash base address and size
# - RAM regions (main SRAM, CCMRAM, backup SRAM)
# - Peripheral memory regions
# - MPU region requirements
2. Define Memory Requirements
## Memory Requirements Analysis
| Component | Flash | RAM | Notes |
|-----------|-------|-----|-------|
| Bootloader | 32K | 8K | Fixed location |
| Application | 480K | 96K | Main firmware |
| Config data | 8K | - | Non-volatile settings |
| OTA staging | 120K | - | A/B update support |
Total Flash: 640K / 1024K (62.5% utilized)
Total RAM: 104K / 128K (81.3% utilized)
3. Generate Linker Script
The skill generates a complete linker script based on requirements:
# Output files:
# - memory.ld - Memory region definitions (included by main)
# - sections.ld - Section definitions (included by main)
# - application.ld - Main application linker script
# - bootloader.ld - Bootloader linker script (if needed)
4. Validate Memory Usage
# Analyze binary size
arm-none-eabi-size firmware.elf
# Detailed map file analysis
arm-none-eabi-nm -S --size-sort firmware.elf
# Generate memory usage report
python scripts/analyze_map.py build/firmware.map
Output Schema
{
"linkerScript": {
"mainScript": "application.ld",
"includes": ["memory.ld", "sections.ld"],
"bootloaderScript": "bootloader.ld"
},
"memoryMap": {
"flash": {
"total": 1048576,
"regions": [
{ "name": "FLASH_BOOT", "origin": "0x08000000", "length": 32768 },
{ "name": "FLASH_APP", "origin": "0x08008000", "length": 491520 }
]
},
"ram": {
"total": 131072,
"regions": [
{ "name": "RAM", "origin": "0x20000000", "length": 131072 }
]
}
},
"symbols": {
"exportedToBootloader": ["_app_start", "_app_end", "_app_checksum"],
"importedFromBootloader": ["_shared_data"],
"stackHeap": ["_estack", "_Min_Heap_Size", "_Min_Stack_Size"]
},
"validation": {
"flashUtilization": 0.625,
"ramUtilization": 0.813,
"mpuCompatible": true,
"warnings": []
},
"artifacts": [
"application.ld",
"bootloader.ld",
"memory.ld",
"sections.ld",
"memory-map.md"
]
}
Common Patterns
RAM Functions (Execute from RAM)
/* Functions copied to RAM for execution (e.g., flash programming) */
.ramfunc :
{
. = ALIGN(4);
_sramfunc = .;
*(.ramfunc)
*(.ramfunc*)
. = ALIGN(4);
_eramfunc = .;
} > RAM AT > FLASH_APP
_siramfunc = LOADADDR(.ramfunc);
Initialized Data (.data section)
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM AT > FLASH_APP
_sidata = LOADADDR(.data);
Zero-Initialized Data (.bss section)
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} > RAM
Stack and Heap
/* User heap and stack */
._user_heap_stack (NOLOAD) :
{
. = ALIGN(8);
PROVIDE(end = .);
PROVIDE(_end = .);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} > RAM
/* Verify sufficient space */
ASSERT((_estack - _ebss) >= (_Min_Heap_Size + _Min_Stack_Size),
"Insufficient RAM for heap and stack")
Best Practices
Memory Alignment
- Align vector table to power of 2 (typically 256 or 512 bytes)
- Align code sections to 4 bytes for ARM
- Align MPU regions to their size (power of 2)
- Align DMA buffers to cache line size
Section Organization
- Keep interrupt vector table at fixed location
- Place frequently executed code in faster memory
- Group related functions to minimize cache misses
- Use KEEP() for sections that might be garbage collected
Safety
- Add ASSERT statements to catch memory overflow
- Define symbols for runtime stack checking
- Reserve space for checksum/signature
- Document all magic numbers
References
- GNU LD Manual: https://sourceware.org/binutils/docs/ld/
- ARM Cortex-M Linker Scripts Application Note
- STM32 Linker Configuration Examples
- Zephyr Memory Configuration Documentation
See Also
memory-architecture-planning.js- Memory planning processbootloader-implementation.js- Bootloader development- SK-010: Memory Analysis skill
- AG-001: Firmware Architect agent