Node:Output Section LMA, Next:Output Section Region, Previous:Output Section Type, Up:Output Section Attributes
Every section has a virtual address (VMA) and a load address (LMA); see Basic Script Concepts. The address expression which may appear in an output section description sets the VMA (see Output Section Address).
The linker will normally set the LMA equal to the VMA. You can change
that by using the AT
keyword. The expression lma that
follows the AT
keyword specifies the load address of the
section. Alternatively, with AT>lma_region
expression,
you may specify a memory region for the section's load address. See MEMORY.
This feature is designed to make it easy to build a ROM image. For
example, the following linker script creates three output sections: one
called .text
, which starts at 0x1000
, one called
.mdata
, which is loaded at the end of the .text
section
even though its VMA is 0x2000
, and one called .bss
to hold
uninitialized data at address 0x3000
. The symbol _data
is
defined with the value 0x2000
, which shows that the location
counter holds the VMA value, not the LMA value.
SECTIONS { .text 0x1000 : { *(.text) _etext = . ; } .mdata 0x2000 : AT ( ADDR (.text) + SIZEOF (.text) ) { _data = . ; *(.data); _edata = . ; } .bss 0x3000 : { _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;} }
The run-time initialization code for use with a program generated with
this linker script would include something like the following, to copy
the initialized data from the ROM image to its runtime address. Notice
how this code takes advantage of the symbols defined by the linker
script.
extern char _etext, _data, _edata, _bstart, _bend; char *src = &_etext; char *dst = &_data; /* ROM has data at end of text; copy it. */ while (dst < &_edata) { *dst++ = *src++; } /* Zero bss */ for (dst = &_bstart; dst< &_bend; dst++) *dst = 0;