目录
1. startup_main.S做了什么
.syntax unified
.section .boot_loader, "ax", %progbits
.thumb
.thumb_func
.align 2
.globl Boot_Loader
.type Boot_Loader, %function
Boot_Loader:
ldr r3, =__StackTop
msr msp, r3 ; // msp是主堆栈指针
bl BootInit
bl NVIC_InitVectors
bl user_secure_boot_init
// 省略部分, 这里包含了从flash加载内容到ram的部分, 不在本文的讨论之内
bl SystemInit
bl _start
我们注意到这段代码里面调用了类似BootInit和NVIC_InitVectors之类的函数, 其中后者完成了fault_handlers的设置
而最后的_start调用跳转到了ctr0.c(见下节)里面去
这段代码在map文件中对应的信息如下:
.boot_text_flash
0x0c000010 0xd98 load address 0x3c000010
*(.boot_loader)
.boot_loader 0x0c000010 0x3c platform/built-in.a(startup_main.o)
0x0c000010 Boot_Loader
这是在best1000.lds.S ()中定义的
根目录Makefile中宏LDS_FILE确定选用best1000.lds.S, 并被扩展为_best1000.lds
ENTRY(Boot_Loader)
SECTIONS
{
__export_fn_rom = (ORIGIN(ROM) + LENGTH(ROM) - ROM_BUILD_INFO_SECTION_SIZE - ROM_EXPORT_FN_SECTION_SIZE);
.boot_struct (ORIGIN(FLASH)) :
{
__flash_start = .;
KEEP(*(.boot_struct))
. = ALIGN(4);
} > FLASH
. = FLASH_TO_FLASHX(.);
.boot_text_flash (.) : AT (FLASHX_TO_FLASH(ADDR(.boot_text_flash)))
{
*(.boot_loader)
*(.boot_text_flash*)
*(.boot_rodata*)
. = ALIGN(4);
} > FLASHX
2. 不可忽略 - C运行时库crt0.o中的_start
C运行时库是为了让C程序跑起来的一组程序. 其中的_start负责C程序的bootup, 他会调用我们的main函数
参考文章: https://blog.csdn.net/weixin_30740295/article/details/96204129
在map文件中我们可以看到相关的内容
.text 0x0c052b68 0x57308 load address 0x3c052b68
*(.text*)
.text 0x0c052b68 0x5c c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7e-m/fpu/crtbegin.o
.text 0x0c052bc4 0x74 c:/program files (x86)/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/crt0.o
0x0c052bc4 _start
0x0c052bc4 _mainCRTStartup
// 部分省略
.text.startup.main
0x0c052cc0 0x1d0 platform/built-in.a(main.o)
0x0c052cc0 main
3. C语言程序的入口main()
在文件{root}\platform\main\main.cpp中
int main(void)
{
// 部分省略
tgt_hardware_setup();
main_thread_tid = osThreadGetId();
hwtimer_init();
// 部分省略
}
欢迎阅读更多 BES专栏文章