Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.
日本語の概要は準備中です。原文の説明を表示しています。
Use when writing a GNU ld script for a bare-metal target, placing code in a flash or RAM region, wiring .data and .bss startup, or fixing a region overflowed error. Not for LTO: use linkers-lto.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
| Field | Bound contract |
|---|---|
| Trigger | A bare-metal image needs a GNU ld script: MEMORY and SECTIONS, VMA versus LMA for .data, the symbols startup code copies between, a function placed in a named region, weak default handlers, or a region overflow error. |
| Authority | Reversible local: writes only the linker script and the startup source in the project directory the user names; rollback is reverting those files in version control. No remote mutation. |
| Side effect | New or edited .ld and startup files. The image layout changes on the next link. |
| Done | The ELF links, readelf -S shows .data with an LMA inside flash and a VMA inside RAM, .bss and the stack fit the RAM region, and the startup code copies .data and zeroes .bss between the script's symbols before main. |
.isr_vector in the CMSIS templates).__libc_init_array and the .init_array sections) or none.Write MEMORY and the skeleton SECTIONS. ENTRY names the reset symbol; KEEP on the vector table stops --gc-sections from removing it; _estack at the top of RAM is where the startup file points the stack. Done when: the script has one MEMORY block with every region from the datasheet and the link succeeds with -T script.ld.
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text .text.*)
*(.rodata .rodata.*)
. = ALIGN(4);
_etext = .;
} > FLASH
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = .;
} > RAM AT > FLASH
_sidata = LOADADDR(.data);
.bss :
{
_sbss = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > RAM
_estack = ORIGIN(RAM) + LENGTH(RAM);
}
Separate VMA from LMA for .data. The VMA is the address the code runs at (RAM); the LMA is where the bytes sit in the image (flash). > RAM AT > FLASH sets both; AT(_etext) after the section name is the equivalent explicit form. LOADADDR(.data) gives startup code the flash copy's address. Done when: arm-none-eabi-readelf -S firmware.elf shows .data with Addr in RAM and arm-none-eabi-objdump -h shows its LMA in flash.
Copy .data and zero .bss in the reset handler, between the script's symbols. With newlib, call __libc_init_array() before main so C++ constructors and .init_array entries run. Done when: a global initialized to a nonzero value reads that value in main, and a zero-initialized global reads zero.
extern uint32_t _sdata, _edata, _sidata, _sbss, _ebss;
void Reset_Handler(void) {
uint32_t *src = &_sidata, *dst = &_sdata;
while (dst < &_edata) *dst++ = *src++;
for (dst = &_sbss; dst < &_ebss; ) *dst++ = 0;
__libc_init_array();
main();
for (;;);
}
The startup file itself is the subject of baremetal-startup; this skill owns the symbols it consumes.
Place code or data in a named region. Give the input section a name with __attribute__((section(".name"))), collect it into an output section with > REGION AT > FLASH, and copy it at startup like .data when the region is RAM. Done when: objdump -h shows the section in the intended region and the copy loop covers it.
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
}
.fast_code :
{
_sfast = .;
*(.fast_code .fast_code.*)
_efast = .;
} > CCM AT > FLASH
_sifast = LOADADDR(.fast_code);
__attribute__((section(".fast_code"))) void critical_isr_handler(void) { }
CCM on STM32F4 is not on the DMA bus; place DMA buffers in SRAM.
Use KEEP, ALIGN, PROVIDE, and the fill expression where each applies. KEEP protects sections --gc-sections would drop (vector table, .init_array). ALIGN(8) before the stack satisfies the AAPCS 8-byte stack alignment. PROVIDE defines a symbol only if no object defines it, which makes it the default a program can override. The =0xFF fill after an output section writes the erased-flash value into gaps. Done when: every KEEP guards a section the code never references directly, and the stack region starts 8-byte aligned.
PROVIDE(_stack_size = 0x400);
.stack (NOLOAD) :
{
. = ALIGN(8);
. += _stack_size;
_stack_top = .;
} > RAM
.text : { *(.text .text.*) . = ALIGN(4); } > FLASH = 0xFF
Give every exception a weak default handler. PROVIDE(NMI_Handler = Default_Handler) in the script, or __attribute__((weak)) in C, binds the vector to a spin loop until the application defines the real symbol. Done when: a firmware with no SysTick_Handler links, and one that defines it calls the definition.
PROVIDE(NMI_Handler = Default_Handler);
PROVIDE(HardFault_Handler = Default_Handler);
PROVIDE(SysTick_Handler = Default_Handler);
__attribute__((weak)) void Default_Handler(void) { for (;;); }
void SysTick_Handler(void) { tick_count++; } /* overrides the default */
Check sizes and addresses after every layout change. --print-memory-usage (pass as -Wl,--print-memory-usage) prints region use at link time; -Wl,-Map=firmware.map writes the symbol map for the big-symbol hunt. Done when: every region is under 100 percent and .data's LMA is inside flash.
arm-none-eabi-size -A firmware.elf
arm-none-eabi-objdump -h firmware.elf
arm-none-eabi-readelf -S firmware.elf
references/linker-script-anatomy.md has a complete STM32F407 script with the ARM unwind and .init_array sections and the table of built-in functions.
| Error | Cause | Fix |
|---|---|---|
region `FLASH' overflowed by N bytes | Image larger than flash | -Os, -ffunction-sections -fdata-sections with -Wl,--gc-sections, LTO; find the big symbols in the map file. |
region `RAM' overflowed | .data, .bss, heap, and stack exceed RAM | Shrink buffers, cut _stack_size or the heap, move constants to const so they land in .rodata. |
undefined reference to '_estack' | Startup expects a symbol the script does not define | Define _estack = ORIGIN(RAM) + LENGTH(RAM);. |
.data reads garbage at boot | LMA equals VMA, or startup copies the wrong range | Add AT > FLASH; copy from LOADADDR(.data) to _sdata up to _edata. |
| Vector table missing from the image | --gc-sections removed it | Wrap it in KEEP. |
cannot open linker script file | Wrong path | Pass -T path/to/script.ld or add -L dir. |
A linker script and startup symbols in the named directory that link the image into the datasheet's regions, with readelf -S and objdump -h output confirming .data LMA in flash and VMA in RAM and every region within its length.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.
日本語の概要は準備中です。原文の説明を表示しています。
Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.
日本語の概要は準備中です。原文の説明を表示しています。
Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.
日本語の概要は準備中です。原文の説明を表示しています。