How do you place an array or function at an exact address (e.g., a DMA buffer or a firmware version block)?
Two complementary parts: a C attribute and a linker-script placement.
In C, tag the symbol with __attribute__((section(".my_section"))) to put it in a custom section, and optionally __attribute__((aligned(N))) for alignment:
__attribute__((section(".dma_buffer"), aligned(32)))uint8_t dma_buf[1024];
In the linker script, add a SECTIONS block for that custom section, choosing where it goes:
.dma_buffer : {. = ALIGN(32);KEEP(*(.dma_buffer))} >RAM
Or for a fixed address:
.fw_metadata 0x0801FF00 : {KEEP(*(.fw_metadata))} >FLASH
Two things to remember: use KEEP() so --gc-sections doesn't drop the section if nothing in C references it (a DMA peripheral reads the buffer by physical address, not by symbol name); for cache-coherent systems (Cortex-M7) also configure the MPU to mark DMA regions as non-cacheable.
The fixed-address pattern is canonical for firmware version blobs (so a bootloader at a known offset can read them), DMA descriptor rings, dual-bank firmware metadata, and any "the hardware expects this at exactly this address" requirement.
Source: Build Systems Q&A
