提问人:Luis Sanchez 提问时间:10/11/2023 最后编辑:Luis Sanchez 更新时间:10/16/2023 访问量:68
lib gcc _init() 函数将地址作为指令执行
lib gcc _init() function executing address as instruction
问:
使用 gcc-arm-none-eabi 和默认 libc 对 cortex M4 目标进行编译将产生一个 _init() 函数,该函数执行内存位置,就好像它是一个函数一样。_()init 的解析是:
0002810c <_init>:
2810c: b5f8 push {r3, r4, r5, r6, r7, lr}
2810e: bf00 nop
00028110 <__frame_dummy_init_array_entry>:
28110: 0000529d muleq r0, sp, r2
28114: bcf8 pop {r3, r4, r5, r6, r7}
28116: bc08 pop {r3}
28118: 469e mov lr, r3
2811a: 4770 bx lr
在指令之后,指令被执行,但这实际上是指向函数的指针。拆解 crtio.o,位于何处,得出的 init 函数确实如上所述。2810e
28110: muleq r0, sp, r2
0000529c <frame_dummy>:
_init()
以下是我们正在使用的相关标志:
-Os -g -mthumb -ffunction-sections -fdata-sections -nostdinc -MD -mcpu=cortex-m4
下面是使用的链接器脚本:
MEMORY
{
FLASH_BOOTLOADER (rx) : ORIGIN = 0x00000000, LENGTH = 0x00003000
FLASH_FIRMWARE (rx) : ORIGIN = 0x00003000, LENGTH = 0x0007D000
RAM_FIRMWARE (xrw) : ORIGIN = 0x20000000, LENGTH = 0x0001FFF8
RAM_BL_NOINIT (rw) : ORIGIN = 0x0001FFF8, LENGTH = 0x8
}
/* Entry Point */
ENTRY(boot)
/* Lowest address of the kernel stack (MSP) */
_estack = 0x200
_sstack = 0;
/* Compatibility with bm startup routines */
_estack_app_stack = _estack;
_sstack_app_stack = _sstack;
/* Define output sections */
SECTIONS
{
/* The main ISR vector table goes first into program FLASH */
/* The vectors follow immediately (aligned) after the bootloader, instead of a fixed adress */
.isr_vector :
{
. = ALIGN(0x0200); /* according to a comment, the ISR vectors must be aligned to 0x200 boundary */
*(.isr_vector)
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH_FIRMWARE
.fwinfo :
{
. = ALIGN(4);
*(.fwinfo_section)
KEEP(*(.fwinfo_section))
. = ALIGN(4);
} >FLASH_FIRMWARE
/* The program code and other data goes into FLASH */
.text ALIGN(4):
{
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH_FIRMWARE
/* Constant data goes into FLASH */
.rodata ALIGN(4):
{
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH_FIRMWARE
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH_FIRMWARE
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH_FIRMWARE
_mdata = .;
. = . + (_edata - _sdata);
_marker_end_of_prg_flash = .;
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
.app_stack (NOLOAD) : AT (0)
{
. = ALIGN(4);
. = . + GLB_STACK_SIZE;
. = ALIGN(4);
} >RAM_FIRMWARE
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
. = ALIGN(4);
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss.fwp_stack)
. = ALIGN(4);
_sbss_dma_buffers = .;
*(.bss.dma_buffers)
. = ALIGN(4);
_ebss_dma_buffers = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM_FIRMWARE
/* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT (_mdata)
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
KEEP(*(.boot_code_in_ram))
. = ALIGN(4);
/* All data end */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_FIRMWARE
/* Non zeroed variables */
.noinit (NOLOAD) :
{
. = ALIGN(4);
_snoinit = .; /* define a global symbol at noinit start */
__noinit_start__ = _snoinit;
*(.noinit)
*(.noinit*)
*(COMMON)
. = ALIGN(4);
_enoinit = .; /* define a global symbol at noinint end */
__noinit_end__ = _enoinit;
} >RAM_FIRMWARE
/*
.check_for_fwp_and_priv_ram (NOLOAD) :
{
. = ALIGN(4);
. = . + FWP_RAM_SIZE;
. = . + PRIVILEGED_DATA_SIZE;
} >RAM_FIRMWARE
*/
/* Used by the startup to initialize data */
/* _si_priv_data = LOADADDR(.privileged_data); */
.boot_shared_ram(NOLOAD) :
{
. = ALIGN(4);
KEEP(*(.boot_shared_ram))
. = ALIGN(4);
} >RAM_BL_NOINIT
/*
.boot_persistant_data :
{
. = ALIGN(4);
_boot_persistant_data = .;
KEEP(*(.boot_persistant_data))
. = ALIGN(4);
} >RAM_PERSISTANT_DATA
*/
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
我们应该如何正确链接 libc 才能正确执行 _init()?
我们还注意到,如果我们添加: -nostartfiles 然后为 提供实现,问题就会得到解决,我仍然想了解以前的链接过程出了什么问题,因为默认实现应该有效。_init()
add: -nostartfiles,然后为 _init() 提供实现。按预期工作。
答: 暂无答案
评论
-mcpu=cortex-m4