Search code examples
assemblyarmlinker-scripts

What are data segment initializers?


I'm constructing a linker script for a bare metal application running on the STM32F3Discovery board. It uses the startup code from the CMSIS drivers located in the STM32Cube_FW_F3 package, precisely the stm32f303xc.s file.

The above file, a fragment of which is pasted below, has a reference to _sidata:

/* start address for the initialization values of the .data section.
defined in linker script */
.word   _sidata
/* start address for the .data section. defined in linker script */
.word   _sdata
/* end address for the .data section. defined in linker script */
.word   _edata
/* start address for the .bss section. defined in linker script */
.word   _sbss
/* end address for the .bss section. defined in linker script */
.word   _ebss

The references to the start and end of the data and bss sections are self explanatory, on the other hand I'm unable to find anything about data segment initializers. It is used directly after the SP is set post-reset.

stm32f303xc.s

    .section    .text.Reset_Handler
    .weak   Reset_Handler
    .type   Reset_Handler, %function
Reset_Handler:
  ldr   sp, =_estack    /* Atollic update: set stack pointer */

/* Copy the data segment initializers from flash to SRAM */
  movs  r1, #0
  b LoopCopyDataInit

CopyDataInit:
    ldr r3, =_sidata
    ldr r3, [r3, r1]
    str r3, [r0, r1]
    adds    r1, r1, #4

LoopCopyDataInit:
    ldr r0, =_sdata
    ldr r3, =_edata
    adds    r2, r0, r1
    cmp r2, r3
    bcc CopyDataInit
    ldr r2, =_sbss
    b   LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
    movs    r3, #0
    str r3, [r2], #4

LoopFillZerobss:
    ldr r3, = _ebss
    cmp r2, r3
    bcc FillZerobss

/* Call the clock system intitialization function.*/
    bl  SystemInit
/* Call static constructors */
    bl __libc_init_array
/* Call the application's entry point.*/
    bl  main

Which fragment of memory should _sidata point at and how is it related to the data segment?


Solution

  • The data segment is going to be located in RAM. Since RAM does not hold its contents on power loss, the initial values of the data segment have to be copied from flash on startup. A copy of the initial content of the .data segment is located at the _sidata label for this purpose; the startup code copies it into the actual data segment.