嵌入式开发(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的链接脚本分析

嵌入式开发(S5PV210)——u-boot的顶层mkconfig文件分析

嵌入式开发(S5PV210)——u-boot的不同来源和目录结构

第一章之s5pv210启动顺序

嵌入式开发(S5PV210)——u-boot的顶层config.mk分析