嵌入式开发(S5PV210)——u-boot启动过程中三次设置栈
Posted 代二毛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入式开发(S5PV210)——u-boot启动过程中三次设置栈相关的知识,希望对你有一定的参考价值。
1、多次设置栈的原因
无论是汇编代码还是C语言代码,当涉及函数嵌套调用时都需要用栈来保存函数返回地址,所以必须设置栈。多次设置栈的原因是,uboot不同的启动阶段可用的内存空间是不同的。最开始只有IRAM可以用,所以只能设置在IRAM中,后来DDR初始化好就将栈设置在DDR中,毕竟IRAM太小了,容易栈溢出。
2、memory map
图中左边是芯片的内存映射图,右边是uboot中第三次设置栈的示意图。IRAM的有效地址是0xD0000000开始,DDR的有效地址是0x20000000到0x80000000,总共1.5G。
3、uboot中设置栈的代码
/第一次/
ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */
sub sp, sp, #12 /* set stack */
mov fp, #0
bl lowlevel_init /* 设置时钟、初始化内存 */
/*开发板供电锁存*/
ldr r0, =0xE010E81C /* PS_HOLD_CONTROL register */
ldr r1, =0x00005301 /* PS_HOLD output high */
str r1, [r0]
/*第二次 get ready to call C functions */
ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */
sub sp, sp, #12
mov fp, #0 /* no previous frame, so fp=0 */
//省略的中间步骤:bl2重定位、开启MMU
//第三次
ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
第一次:
当前设置是在启动的早期阶段,程序还在IRAM中运行,DDR还没有初始化,因此栈只能设置在IRAM中。0xd0036000是IRAM中的地址,栈不是必须设置在改地址,你可以在IRAM中找任意一个地址,前提是栈空间不会发生踩踏。
第二次:
此次设置是在DDR初始化之后,此时DDR可以使用,所以将栈指针指向0x33e00000。0x33e00000是uboot的链接地址,uboot会被重定位到0x33e00000,但是uboot所在内存空间是0x33e00000往上,而栈空间是0x33e00000往下(这里有个隐含知识:RAM的栈是满减栈),所以内存不会发生踩踏。
第三次:
此次设置是BL2重定位之后,整个uboot都全部加载到DDR中,将SP栈指针设置在[0x33E00000+ 2M – 4K]地址处,可用的栈空间就是(2M – 4K - uboot),一般uboot不会很大,在几百KB;参考memory map中对sp的设置示意图。
以上是关于嵌入式开发(S5PV210)——u-boot启动过程中三次设置栈的主要内容,如果未能解决你的问题,请参考以下文章
嵌入式开发(S5PV210)——u-boot的顶层Makefile分析
嵌入式开发(S5PV210)——u-boot的顶层mkconfig文件分析