设置完寄存器控制器后,则跳出cpu_init_crit,进入_main 函数。即进入crt0.S (archarmlib)
跟着代码流程慢慢走
一、crt0.S
1.1 第一步执行代码
1 /* 预设堆栈指针为CONFIG_SYS_INIT_SP_ADDR */ 2 /* #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE) */ 3 /* #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 */ 4 /* #define PHYS_SDRAM_1 0x30000000 SDRAM Bank #1 */ 5 /* #define GENERATED_GBL_DATA_SIZE 176 */ 6 /* CONFIG_SYS_INIT_SP_ADDR = 0x3000 0000 + 0x1000 - 176 */ 7 /* 这里是预设的堆栈地址,而不是最终的堆栈地址 */ 8 ldr r0, =(CONFIG_SYS_INIT_SP_ADDR) /* 0x3000 0f52*/ 9 bic r0, r0, #7 /* 8字节对齐后为,0x3000 0f50 */ 10 mov sp, r0 /* sp 指针指向 0x3000 0f50 */ 11 bl board_init_f_alloc_reserve /* 给 gd 分配内存大小, 通过 u-boot.dis 文件可知 gd 大小为168 */
跳转到 board_init_f_alloc_reserve 中执行:
1 /* 这个函数用于给global_data分配空间,在relocation之前调用 2 * 传入的参数是顶部地址,但是不一定是要内存顶部的地址,可以自己进行规划 3 */ 4 ulong board_init_f_alloc_reserve(ulong top) 5 { 6 /* Reserve early malloc arena */ 7 /* 先从顶部向下分配一块CONFIG_SYS_MALLOC_F_LEN大小的空间给early malloc使用 */ 8 /* 关于CONFIG_SYS_MALLOC_F_LEN可以参考README */ 9 /* 这块内存是用于在relocation前用于给malloc函数提供内存池。 */ 10 #if CONFIG_VAL(SYS_MALLOC_F_LEN) 11 top -= CONFIG_VAL(SYS_MALLOC_F_LEN); 12 #endif 13 /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */ 14 /* 继续向下分配sizeof(struct global_data)大小的内存给global_data使用,向下16byte对齐 */ 15 /* 这时候得到的地址就是global_data的地址。 */ 16 top = rounddown(top-sizeof(struct global_data), 16); 17 18 return top; /* 将top,也就是global_data的地址返回 */ 19 }
设置完后,返回继续执行crt0.S中的代码:
1 mov sp, r0 /* 分配后的栈顶为 3000 0de0,16字节对其后为 3000 0de0 */ 2 /* set up gd here, outside any C code */ 3 mov r9, r0 4 bl board_init_f_init_reserve /* 启动前初始化完成 */
进入 board_init_f_init_reserve 中执行:
1 /* 这个函数用于对global_data区域进行初始化,也就是清空global_data区域 */ 2 /* 传入的参数就是global_data的基地址 */ 3 void board_init_f_init_reserve(ulong base) 4 { 5 struct global_data *gd_ptr; 6 7 /* 8 * clear GD entirely and set it up. 9 * Use gd_ptr, as gd may not be properly set yet. 10 */ 11 12 gd_ptr = (struct global_data *)base; 13 /* zero the area, 先通过memset函数对global_data数据结构进行清零 */ 14 memset(gd_ptr, '