К основному содержанию
скилл CX Codex

linker-scripts — скилл для Claude Code: скрипты GNU ld

Помогает писать и править скрипты компоновщика GNU ld для bare-metal: регионы памяти, VMA и LMA, инициализация .bss и .data.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add mohitmishra786/low-level-dev-skills --skill linker-scripts -a claude-code
Открыть на GitHub

Что делает linker-scripts

Скилл включается, когда агент берётся за MEMORY и SECTIONS в скрипте компоновщика: разложить код и данные по конкретным областям flash и RAM, разобраться, чем VMA отличается от LMA, настроить копирование .data из flash в RAM и обнуление .bss до входа в main(). Внутри — разбор анатомии скрипта на примере Cortex-M, таблица частых ошибок компоновки вроде переполнения региона FLASH и приёмы с KEEP, ALIGN, PROVIDE и слабыми символами.

Отдельный блок про размещение кода в нужной области: секция .fast_code с атрибутом section уезжает в CCM RAM, а AT(_etext) задаёт LMA для .data. Для проверки результата скилл опирается на arm-none-eabi-size, objdump -h и readelf -S — без них адреса секций не увидеть.

Скилл рассчитан на embedded-проекты с GNU ld. Если вы собираете под проприетарный тулчейн или линкуете обычное десктопное приложение, примеры здесь не пригодятся. Смежные скиллы того же набора закрывают прошивку через OpenOCD, размещение кучи FreeRTOS и LTO.

Какие задачи решает

  • разложить код и данные по регионам flash и RAM
  • понять, где секция выполняется, а где хранится
  • настроить копирование .data и обнуление .bss на старте
  • разобраться с ошибкой переполнения региона
  • закрепить обработчик прерывания за конкретным адресом

Примеры запросов агенту

  • Напиши скрипт компоновщика для Cortex-M: flash 512K с 0x08000000, RAM 128K с 0x20000000
  • Почему .data оказалась не по тому адресу? Проверь LMA и добавь AT(_etext)
  • Вынеси critical_isr_handler в секцию .fast_code и размести её в CCM RAM

Как установить linker-scripts

1Через Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill linker-scripts -a claude-code

2Вручную: положить файлы

~/.claude/skills/linker-scripts/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/linker-scripts/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о linker-scripts

Как установить linker-scripts в Claude?

Выполните npx skills add mohitmishra786/low-level-dev-skills --skill linker-scripts -a claude-code. После этого файл скилла окажется в ~/.claude/skills/linker-scripts/SKILL.md.

Что делает linker-scripts?

Ведёт агента по написанию и правке скриптов GNU ld: команды MEMORY и SECTIONS, различие VMA и LMA, инициализация .bss и .data при старте, размещение функций в заданных областях памяти.

Чем этот скилл отличается от linkers-lto?

linker-scripts про сам скрипт компоновки и раскладку секций, а skills/binaries/linkers-lto — про LTO и флаги символов. Для проверки размеров и адресов секций рядом есть skills/binaries/elf-inspection.

Исходный текст

SKILL.md · MIT
---
name: linker-scripts
description: Linker script skill for embedded bare-metal targets. Use when writing or modifying GNU ld linker scripts, placing code and data in specific flash or RAM regions, understanding VMA vs LMA, configuring startup .bss/.data initialization, using MEMORY and SECTIONS commands, or debugging linker errors about regions. Activates on queries about linker scripts, MEMORY command, SECTIONS command, .bss init, VMA vs LMA, weak symbols, or placing functions in specific memory regions.
---

# Linker Scripts

## Purpose

Guide agents through writing and modifying GNU ld linker scripts for embedded targets: MEMORY and SECTIONS commands, VMA vs LMA for code relocation, startup `.bss`/`.data` initialization, placing sections in specific regions, and using PROVIDE/KEEP/ALIGN directives.

## Triggers

- "How do I write a linker script for my MCU?"
- "How do I place a function in a specific flash/RAM region?"
- "What's the difference between VMA and LMA in a linker script?"
- "How does .bss and .data initialization work at startup?"
- "Linker error: region 'FLASH' overflowed"
- "How do I use weak symbols in a linker script?"

## Workflow

### 1. Linker script anatomy

```ld
/* Minimal Cortex-M linker script */

ENTRY(Reset_Handler)            /* entry point symbol */

MEMORY
{
    FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 512K
    RAM   (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

SECTIONS
{
    .text :                     /* code section */
    {
        KEEP(*(.isr_vector))    /* interrupt vector must be first */
        *(.text)
        *(.text.*)
        *(.rodata)
        *(.rodata.*)
        . = ALIGN(4);
        _etext = .;             /* end of flash content */
    } > FLASH

    .data : AT(_etext)          /* VMA = RAM, LMA = FLASH */
    {
        _sdata = .;
        *(.data)
        *(.data.*)
        . = ALIGN(4);
        _edata = .;
    } > RAM

    .bss :
    {
        _sbss = .;
        *(.bss)
        *(.bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = .;
    } > RAM

    /* Stack at top of RAM */
    _estack = ORIGIN(RAM) + LENGTH(RAM);
}
```

### 2. VMA vs LMA

- **VMA** (Virtual Memory Address): where the section runs at runtime
- **LMA** (Load Memory Address): where the section is stored in the image (flash)

For `.data`: stored in flash (LMA), copied to RAM at startup (VMA).

```ld
/* AT() sets LMA explicitly */
.data : AT(ADDR(.text) + SIZEOF(.text))
{
    _sdata = .;
    *(.data)
    _edata = .;
} > RAM          /* VMA goes in RAM */
```

LMA of `.data` is automatically placed after `.text` if you use `AT(_etext)`.

### 3. Startup .bss / .data initialization

The C runtime must copy `.data` from flash to RAM and zero `.bss` before `main()`:

```c
// startup.c or startup.s equivalent in C
extern uint32_t _sdata, _edata, _sidata; // _sidata = LMA of .data
extern uint32_t _sbss, _ebss;

void Reset_Handler(void) {
    // Copy .data from flash to RAM
    uint32_t *src = &_sidata;
    uint32_t *dst = &_sdata;
    while (dst < &_edata) *dst++ = *src++;

    // Zero-initialize .bss
    dst = &_sbss;
    while (dst < &_ebss) *dst++ = 0;

    // Call C++ constructors
    // (call __libc_init_array() if using newlib)

    main();
    for (;;);  // should never return
}
```

Linker script provides `_sidata` (LMA of `.data`):

```ld
.data : AT(_etext)
{
    _sdata = .;
    *(.data)
    _edata = .;
} > RAM

_sidata = LOADADDR(.data);    /* LMA of .data for startup code */
```

### 4. Placing code in specific regions

```ld
/* Place time-critical code in RAM for faster execution */
MEMORY
{
    FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
    RAM   (rwx): ORIGIN = 0x20000000, LENGTH = 128K
    CCM   (rwx): ORIGIN = 0x10000000, LENGTH = 64K   /* Cortex-M4 CCM */
}

.fast_code : AT(_etext)
{
    _sfast = .;
    *(.fast_code)   /* sections marked __attribute__((section(".fast_code"))) */
    _efast = .;
} > CCM              /* runs from CCM RAM */
```

```c
// Mark a function to go in fast_code section
__attribute__((section(".fast_code")))
void critical_isr_handler(void) {
    // runs from CCM RAM
}
```

### 5. KEEP, ALIGN, PROVIDE

```ld
/* KEEP — prevent garbage collection of section */
KEEP(*(.isr_vector))        /* linker gc won't remove interrupt table */
KEEP(*(.init))
KEEP(*(.fini))

/* ALIGN — advance location counter to alignment boundary */
. = ALIGN(8);               /* align to 8 bytes */

/* PROVIDE — define symbol only if not already defined (weak default) */
PROVIDE(_stack_size = 0x400);  /* default 1KB stack; override in code */

/* Symbols for stack */
.stack :
{
    . = ALIGN(8);
    . += _stack_size;
    _stack_top = .;
} > RAM

/* FILL — fill unused bytes */
.text :
{
    *(.text)
    . = ALIGN(4);
    FILL(0xFF)             /* fill flash gaps with 0xFF (erased state) */
} > FLASH
```

### 6. Weak symbols

```ld
/* In linker script — provide weak default ISR */
PROVIDE(NMI_Handler        = Default_Handler);
PROVIDE(HardFault_Handler  = Default_Handler);
PROVIDE(SysTick_Handler    = Default_Handler);
```

```c
// In C — weak default handler
__attribute__((weak)) void Default_Handler(void) {
    for (;;);  // spin — override this in application
}

// Override by defining a non-weak symbol with the same name
void SysTick_Handler(void) {
    tick_count++;
}
```

### 7. Common linker errors

| Error | Cause | Fix |
|-------|-------|-----|
| `region 'FLASH' overflowed` | Binary too large for flash | Enable LTO, `-Os`, remove unused code; `--gc-sections` |
| `region 'RAM' overflowed` | Too much RAM used | Reduce stack size, use static buffers, check `.bss` size |
| `undefined reference to '_estack'` | Missing linker script symbol | Define `_estack` in linker script |
| `no rule to process file` | `.ld` extension not recognized | Pass with `-T script.ld` |
| `cannot find linker script` | Wrong path | Use `-L dir -T name.ld` |
| Data section `.data` at wrong address | LMA not set | Add `AT(_etext)` after `.data` section definition |

```bash
# Analyze section sizes
arm-none-eabi-size firmware.elf
arm-none-eabi-size -A firmware.elf    # verbose per-section

# Show all sections and their addresses
arm-none-eabi-objdump -h firmware.elf

# Check if .data LMA is in flash range
arm-none-eabi-readelf -S firmware.elf | grep -A2 "\.data"
```

For linker script anatomy details, see [references/linker-script-anatomy.md](references/linker-script-anatomy.md).

## Related skills

- Use `skills/embedded/openocd-jtag` for flashing to addresses defined in linker script
- Use `skills/embedded/freertos` for FreeRTOS heap placement in specific RAM regions
- Use `skills/binaries/linkers-lto` for linker LTO and symbol flags
- Use `skills/binaries/elf-inspection` to inspect section sizes and addresses

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Похожие скиллы

Все скиллы по теме «Языки программирования» →
arm-cortex-expert Ryan Snodgrass Пишет драйверы и прошивки под ARM Cortex-M: Teensy, STM32, nRF52, SAMD. Помогает, когда код работает с отладочной печатью и падает без неё. CX Codex ★ 41 729звёзд репо csharp-scripts dotnet Запускает C#-код из одного файла через dotnet, без создания проекта. Пригодится для проверки языковой фичи или мелкой утилиты. CX Codex +1 3 800установок freecad-scripts официальный github Помогает писать Python-скрипты и макросы для FreeCAD: 3D-геометрию, параметрические объекты, GUI на PySide. Пригодится, если вы автоматизируете CAD. 1 200установок rhino3d-scripts официальный github Помогает писать и отлаживать скрипты для Rhinoceros 3D на Python, VBScript и C#. Пригодится для автоматизации геометрии, макросов и слоёв в Rhino 8. 89установок domain-embedded actionbook Направляет работу с embedded и no_std Rust: памятью, прерываниями и периферией. Пригодится при разработке прошивок для микроконтроллеров. CX Codex +1 2 900установок mspm0-ccs mc3545dada Набор правил для агента, который правит прошивку MSPM0: подсказывает, что менять в .syscfg, а какие файлы трогать нельзя. CX Codex +1 500установок

Из того же набора62

cpp-modules Скилл для работы с модулями C++20: именованные модули, партиции, header units, сборка через CMake и флаги компиляторов. CX Codex +1 555установок rust-security Скилл для проверки Rust-проектов на уязвимости: cargo-audit, cargo-deny, RUSTSEC, безопасный FFI, фаззинг и Miri. CX Codex +1 544установок debug-optimized-builds Помогает разобраться, почему GDB показывает «value optimized out» и как вообще отлаживать код, собранный с оптимизацией. CX Codex +1 533установок concurrency-debugging Скилл ведёт агента по отчётам ThreadSanitizer, графам блокировок Helgrind и зависшим потокам в GDB. Пригодится, когда программа падает или виснет на многопоточке. CX Codex +1 524установок wasm-emscripten Скилл ведёт агента через сборку C и C++ в WebAssembly: подбор флагов emcc, экспорт функций, модель памяти, Asyncify и отладка .wasm. CX Codex +1 513установок zig-debugging Скилл для ИИ-агента: разбирает паники Zig, error return traces и сессии GDB/LLDB. Пригодится, когда программа падает, а стек нечитаемый. CX Codex +1 511установок zig-build-system Помогает агенту писать и отлаживать build.zig: исполняемые файлы, библиотеки, C-исходники, опции сборки и тесты. CX Codex +1 508установок build-acceleration Скилл для ИИ-агентов, который помогает разобраться, почему сборка C/C++ идёт медленно, и настроить кэш, распределённую компиляцию и PCH. CX Codex +1 506установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой