I'm just getting started with embedded arm development, and there's a snippet of code that's really bugging me:
/* Initialize the relocate segment */
pSrc = &_etext;
pDest = &_srelocate;
if (pSrc != pDest)
{
while (pDest < &_erelocate)
{
*pDest++ = *pSrc++;
}
}
Where _etext
and _srelocate
are symbols defined in the linker script:
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
Where ram
is a memory segment whose origin is 0x20000000
. The issue as I see it is that _etext
is a symbol that marks the end boundary of the .text
segment, which is a part of a different memory segment, rom
. This means that unless the aforementioned memory segment was 100% full, _etext != _srelocate
will always be true. What this means is that we're copying memory beyond the .text
section where nothing is defined to live according to the linker script.
To me, this leads to one of three scenarios, either A) There is garbage present in rom
beyond the .text
section, and it gets copied into .relocate
(and subsequently .data
), or B) The memory beyond .text
is empty following a chip erase operation prior to device programming, in which case .relocate
is zeroed, or C) There is some slight of hand magic happening here where .data
values are placed after .text
in rom
, and must be loaded into ram
; in which case the comment should be s/relocate/data
.
The third scenario seems the most likely, but according to the linker script this can't be true. Can someone shed some light on this?
You're right, it's the third option. The AT() tells the linker to put the .ramfunc and .data sections (both of which are read/write) in the object file starting at _etext. The "> ram" tells the linker to resolve relocations as if the sections were placed in RAM this is done using a MEMORY command as decribed here: https://sourceware.org/binutils/docs/ld/MEMORY.html#MEMORY The result is that the copy loop moves the data from the read only area to the read/write area when the program starts up.
Here's a link to the gnu ld documentation where controlling the LMA (load address) is described: https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With