Reputation: 2022
I have a linker script for an embedded system that's doing some relocations (code that is loaded onto the flash of the device, but copied to RAM on boot for execution). It's using the AT feature of the linker, which seems designed to do this.
The problem is that the size of the relocation section is currently only charged to the ram
memory region, when in practice it should be charged to both the rom
and ram
regions (it occupies the former when the device is at rest and the latter when it's active). Currently, if the data
alone fits in rom
but the data + relocation
exceeds rom
, you won't get any errors or warnings.
How do I get the .relocate
section to charge its size to both the rom
and ram
memory regions?
Minimalized linker script:
MEMORY
{
rom (rx) : ORIGIN = ROM_ORIGIN, LENGTH = ROM_LENGTH
ram (rwx) : ORIGIN = RAM_ORIGIN, LENGTH = RAM_LENGTH
}
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
SECTIONS
{
.text :
{
. = ALIGN(4);
_stext = .; /* First of standard s,e (start/end) pair */
KEEP(*(.vectors .vectors.*))
KEEP(*(.irqs))
*(.text .text.* .gnu.linkonce.t.*)
*(.rodata .rodata* .gnu.linkonce.r.*)
} > rom
/* Mark the end of static elements */
. = ALIGN(4);
_etext = .;
/* This is program data that is exepected to live in SRAM, but is
* initialized with a value. This data is physically placed into flash and
* is copied into SRAM at boot. The symbols here will be defined with
* addresses in SRAM.
*
* This is the section that needs to be charged to BOTH rom and ram */
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
.sram (NOLOAD) :
{
. = ALIGN(8);
_sstack = .;
. = . + __stack_size__;
. = ALIGN(8);
_estack = .;
/* BSS section. Memory that is expected to be initialized to zero. */
. = ALIGN(4);
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ezero = .;
} > ram
}
Or here is the complete linker script file.
Upvotes: 3
Views: 1788
Reputation: 2022
We managed to solve this. The solution is to change how the location of the relocate
section is specified, specifically, this is wrong:
# Bad:
.relocate : AT (_etext)
{
...
} > ram
Rather, the AT
directive should go at the end, like this:
# Correct
.relocate :
{
...
} > ram AT > rom
This will cause the linker to charge the size of .relocate
to both ram
and rom
, while placing the section "physically" in rom
.
(Final applied patch to the full linker script linked in the question)
Upvotes: 3