I'm trying to create an extra ram section (in my GNU linker script) for initialized data, in my ARM MCU. The section will have to be placed at a known address, so that I can set specific attributes for it in the MPU. I'm having some trouble with all the linker magic.
The memory is divided as follows:
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00420200, LENGTH = 0x001DFE00
ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x0005e000
ram_nocache_section (rwx) : ORIGIN = 0x2045e000, LENGTH = 0x00002000
sdram(rwx): ORIGIN = 0x70000000, LENGTH = 0x00200000
}
It's the "ram_nocache_section" that I'm trying to handle.
I can define an appropriate section as follows:
/* no cache section */
.ram_nocache :
{
. = ALIGN(8);
*(.ram_nocache)
} > ram_nocache_section
This works, but the resulting binary is gigantic. 0.5 GB. This is because the ram address space is 0.5 GB apart from the flash address space. The way to deal with this, is to 'relocate' the initialized ram data. The script performs this like so:
.text :
{
...
} > rom
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
This will magically allocate initialized data (and ram functions) both in flash and in ram. So this would be easy just to copy, right? Like so:
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
. = ALIGN(4);
_eramdata = .;
.relocate2 : AT ( _eramdata )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
This will compile, but the resulting binary is still gigantic. This is because the _eramdata symbol is somehow placed in ram and not in flash like the _etext.
Well then... According to this document, I should be able to do something like this instead:
.relocate2 : AT ( _etext + SIZEOF(.data) + SIZEOF(.ramfunc) )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
This wont compile though. Instead I can create the desired result like so:
.relocate2 : AT ( _etext + 10k )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
However, this is a rather fragile and wasteful solution.
How do I do this properly? I want to place the 'relocate2' section right next to the regular 'relocate' section. Without any excess waste or predefined code limits.
NOINIT
attribute. – too honest for this site.data
section then? And you don't have a load memory specified. – too honest for this site