- 接下来紧挨着u-boot之start.S分析(三)最后的代码分析
再次设置栈
skip_hw_init:
/* Set up the stack */
stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#if defined(CONFIG_USE_IRQ)
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
#endif
- 通过查询可知,我们是定义了
CONFIG_MEMORY_UPPER_CODE
的,因此栈指针sp被设置为CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000
,即为0xc3e00000+2x1024x1024-0x1000=0xC3FFF000
,对应的真实地址为0x33fff000
- 意思就是在uboot的地址上加2M再减4K的地方,由于ARM是满减栈,因此从此位置开始往下大约2M就是栈的使用空间
清理BSS段
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
_bss_start
和_bss_end
来源于链接器脚本(中间省略一层定义的描述)
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
启动start_armboot
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot
_start_armboot:
.word start_armboot
- 至此,第一阶段分析完成
start_armboot
函数位于uboot/lib_arm/board.c
中,是一个C语言函数- 最后通过
lpr
远跳转指令执行函数start_armboot
- 远跳转的含义就是这句话加载的地址和当前运行地址无关,而和
链接地址
有关
- 在u-boot之start.S分析(一)中,将栈设置到了内部的SRAM中,大概只有8K大小,uboot在此执行部分代码
- 在u-boot之start.S分析(三)中,将栈重新设置到了已经初始化完成的DDR中
- 最后再重新规划DDR的使用,重新设置栈,设置完成后跳转到DDR中执行第二阶段。