Luke’s right. The startup code (
start.S) should copy the initialised data over to the data RAM.
It might help to have a look at the linker script (
sections.lds) and the
firmware.map file that gets produced during the build to get an idea of where things are going.
const values should end up in flash (
.text / .rodata), uninitialised data in
bss, and initialised in the
.data / .sdata sections.
If you look at the
sections.lds file, you’ll notice that at the end of the
.data section there’s a marker called “
_sidata”. This is used by the startup code as a pointer to where the initialised data sits in the flash memory image.
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.srodata) /* .rodata sections (constants, strings, etc.) */
*(.srodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
The data is then copied from there to RAM (ie. to the .data section) by the startup code.
.data section is bookended by
_edata markers which are used to signify the start and end of data RAM.
The part of the
start.S file that copies data across looks like this:
# copy data section
la a0, _sidata
la a1, _sdata
la a2, _edata
bge a1, a2, end_init_data
lw a3, 0(a0)
sw a3, 0(a1)
addi a0, a0, 4
addi a1, a1, 4
blt a1, a2, loop_init_data
The other thing that needs to happen on startup is that the
bss segment needs to be initialised to all zeros (and the registers probably ought to be zeroed too)…