I am using the STM32F746NG microcontroller from STMicroelectronics. This device is based on the ARM Cortex-M7 architecture. I spent quite a bit of time understanding linkerscript from sample projects. I understood the basics, but I still can not understand the big parts. Please help me understand these parts.
Linker Start
Linkestra begins as follows:
ENTRY(Reset_Handler) _estack = 0x20050000; _Min_Heap_Size = 0x200; _Min_Stack_Size = 0x400; MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K }
Vector table and program code
After defining memory areas, the linkstream continues to define sections. The first section defined in the linker is a vector table. It should end in the first bytes of flash memory.
/* --------------------------------------------------------------------*/ /* OUTPUT SECTIONS */ /* --------------------------------------------------------------------*/ SECTIONS { /****************************/ /* VECTOR TABLE */ /****************************/ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Vector Table */ . = ALIGN(4); } >FLASH
After the vector table is inserted, this is the time for the program code:
.text : { . = ALIGN(4); *(.text) *(.text*) *(.glue_7) *(.glue_7t) *(.eh_frame) KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; } >FLASH
Linkerscript defines a global e_text character that represents the address where program code ends in flash memory.
Persistent data
Read-only data also ends up in flash memory (it makes no sense to put it in RAM, which is volatile). Linkerscript determines that the .rodata section must be in flash:
/****************************/ /* CONSTANT DATA */ /****************************/ .rodata : { . = ALIGN(4); *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ . = ALIGN(4); } >FLASH
Mysterious sections in flash memory
After determining where read-only permanent data should go, the link script determines that several "mysterious" partitions should also end in flash memory:
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT(.fini_array.*))) KEEP (*(.fini_array*)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH
I have no idea what these sections are. Therefore, let this be the first question. What are these sections and in which object files do they appear? As you know, linker script needs to link some object files. I do not know in what object files these mysterious sections exist:
.ARM.extab.ARM.preinit_array.init_array.fini_array
This is the end of the flash allocation. Linkerscript continues with defining sections that end in RAM.
Sections in RAM
The .data and .bss sections are clear to me. No questions about this.
/****************************/ /* INITIALIZED DATA */ /****************************/ _sidata = LOADADDR(.data); .data : { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH /****************************/ /* UNINITIALIZED DATA */ /****************************/ . = ALIGN(4); .bss : { _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM
Linkerscript also defines the ._user_heap_stack section:
/****************************/ /* USER_HEAP_STACK SECTION */ /****************************/ /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : { . = ALIGN(8); PROVIDE ( end = . ); PROVIDE ( _end = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); } >RAM
This section does not appear to be used immediately. It is determined only to check if RAM has enough space for the stack and heap. Linker error occurs when it is not ( . Exceeds the upper RAM address).
Linker End
Here's how the linker ends. And honestly, I have no idea what he is doing. So this is the second question: what does the following mean?
/* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } .ARM.attributes 0 : { *(.ARM.attributes) } } /* END OF LINKERSCRIPT */