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 = .);
. = . + _M