2.2 uboot SPL阶段
自2012年以后,uboot分为了uboot-spl和uboot两个组成部分。SPL即Secondary Program Loader的简称,第二阶段程序加载器,这里所谓的第二阶段是相对于SOC中固化ROM中的启动,即RBL(ROM BootLoader)。
2.2.1 为什么uboot要增加SPL
一般厂商固化的RBL上电后会通过相关的硬件引脚电平来判断开发者期望他去加载UBL(User BootLoader)的方式,比如eMMC、MMC/SD、SPI Flash、NandFlash、NorFlash等,由于在上电初期,DDR还未初始化,这个阶段UBL是被加载到Soc的片上RAM来去执行的,然而RAM是很贵的,SocRAM一般在4K~128K左右,Soc厂商是不会把RAM的空间做到足够容纳整个Uboot的。
以三星的S3C2440为例,S3C2440处理器的内部RAM只有4K字节,但对于uboot编译出的可执行文件来说,肯定是不够用的,当然uboot也是可以裁剪的,你也可以将uboot裁剪到4K以内,不过我不建议你这么做,因为以牺牲uboot的一些调试功能为代价,这样得不偿失,Linux环境下的调试本身就极为复杂,当你调试板卡的时候更能体会这点。
在没有SPL之前,S3C2440上电后,RBL将NandFlash中的前4K数据(也即uboot的前4K)搬移至内部RAM,这时RAM中的uboot代码并不是完整的,不过也没关系,根据程序运行的局部性,只要我们在RAM有限的空间里能够执行到代码重定位部分即可,这也是uboot的链接脚本中要把start.o链接到代码段最前端的原因,因为uboot的代码重定位必须要在前128K代码里完成。
自从有了SPL后,Uboot再也不用再自己给自己重定位了,即Uboot的链接地址就是它最后要运行的地址了,这个启动过程变为了上电后,RBL去加载存储介质中的SPL,SPL初始化Uboot的运行环境后(如初始化DDR、时钟等必要外设),再去存储介质中加载uboot至DDR链接地址处,然后跳转至DDR去运行uboot。
2.2.2 为什么我们不需要SPL
uboot作为一款通用bootloader,需要照顾到大多数的处理器,对于一些早期的处理器,SPL是很有用的,对于类似omapl138处理器来说,SPL就显得没神马必要了。
因为在omapl138处理器上的代码重定位根本不需要我们用户来做,如果你领会了上一节的内容,那么就应该知道需要做重定位的处理器都满足以下两个特征:
- 上电DDR需要用户的bootloader进行初始化
- 上电后可执行文件不能直接被加载到链接地址
以上两个特征,omapl138都不满足,还记得我们的AIS工具吗?如果你对TI的AIS已经有所了解,你就会明白omapl138为什么可以不需要SPL和代码重定位,这里就不再讲解了。
既然uboot出了SPL这个功能,我们就紧跟一下时代的步伐,体验一下总是没有坏处的嘛。