我正在为运行在STM32F3Discovery开发板上的裸机应用构建链接脚本。它使用位于STM32Cube_FW_F3包中的CMSIS驱动程序的启动代码,准确地说是stm32f303xc.s文件。
上述文件(以下是一部分),引用了_sidata:
上述文件(以下是一部分),引用了_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
关于数据和bss段的起始和结束的引用是不言自明的,但是我无法找到有关数据段初始化器的任何信息。它会在复位后直接在SP设置之后使用。
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
< p > _sidata
应该指向哪个内存片段,它与数据段有什么关系?
_sidata
应该指向.data
段的加载地址,这个地址在 ROM 中? - bartlomiej.n_sidata
是位于 ROM 中的数据段的副本。实际的.data
段位于 RAM 中。 - fuz.data
位于RAM中,那么链接器脚本中的_sidata
符号应该指向哪里呢?还是应该在应用程序自身中硬编码地址,根据其在ROM中的位置确定地址? - bartlomiej.n_sidata
指向加载地址。加载地址或LMA是ROM地址。'虚拟'地址或VMA是RAM中的地址。这是因为链接器文档是使用OS原始副本(LMA)和应用程序的MMU映射地址(VMA)的概念编写的。然而,这些名称对于Flash/ROM和RAM应用程序没有意义。因此,正确的答案是不要那样想...指的是GNU ld。 - artless noise