I have a program that's resident in flash and will run from flash. Early in the program data segments are copied from flash to ram. I'm using a linker script like (simplified):
.text :
{
*(.text)
} > FLASH
_etext = .;
PROVIDE (etext = .);
.rodata :
{
PROVIDE(__COPY_DATA_START__ = .);
*(.rodata)
} > ram AT>flash
PROVIDE (__SDATA2_START__ = .);
.sdata2 :
{
*(.sdata2)
} > ram AT>flash
PROVIDE (__sbss2_start = . );
.sbss2 : {
*(.sbss2)
. = ALIGN(4)
} > ram AT>flash
PROVIDE (__sbss2_end = . );
PROVIDE (__SBSS2_END__ = .);
.data :
{
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
*(.eh_frame)
} > ram AT>flash
PROVIDE (__END_COPY__ = .);
I want the sections to be aligned on 4-byte boundaries (architecture is PowerPC 32-bit). Some of the data sections include sub-word items. I'm finding that the ALIGN instruction aligns the VMA address in RAM but doesn't align the LMA. So my copy-to-ram routine fails because the two areas don't correspond byte-for-byte.
My copy routine looks like
r3 = address in flash of _etext
r4 = address in ram of __COPY_DATA_START__
words to copy = (__END_COPY__ - COPY_DATA_START) / 4
while (words to copy)
* r4++ = *r3++
When the loop gets to an aligned bit, the destination points to some pad bytes, but the source data doesn't include the align-padding so the data gets put too early in memory.
I can tell this from the map file because it looks like (contrived example)
.rodata 0x00000000 0xb15 load address 0xfff13000
0x00000000 PROVIDE (__COPY_DATA_START__, .)
.sdata 0x00000b18 0x10 load address 0xfff13b15 <<< origin 0xb18 is aligned but load address hasn't moved on by the padding bytes
Does anyone know the solution to this problem?
Thank you
Chris