u-boot (3) —— spl

目录

1、SPL 名字由来

2、SPL 拿来干嘛

2.1、铺垫

2.2、spl


u-boot 里面,有一个叫做 SPL 的东东,你在看 u-boot 代码的时候,很多地方都可以看到和他相关的东西,这里聊一下这玩意到底是拿来干啥用的;

1、SPL 名字由来

SPL 全称叫做:Secondary Program Loader,看名字,像是一个什么二级加载相关的;实质上,也是二级加载;

众所周知,u-boot 是用来 boot 我们的嵌入式系统的,那直接使用 u-boot 就行了呗,为何还会多出一个 uboot spl 呢?那我们从系统启动开始说起吧;

站在芯片厂商的角度来说,硬件系统一上电,一定是要去某个地址取指令(一般是 0x00000000),然后软件便开始很欢快的运行起来了;通常来讲,SoC 厂家都会做一个 ROM 在 SoC 内部,这个 ROM 很小(成本,你懂的),里面固化了上电启动的代码(一经固化,永不能改,是芯片做的时候,做进去的);这部分代码呢,我们管它叫做 BootROM(或者你随便叫也行)笔者常年混迹半导体公司,有幸从头到尾,自己写完过一个这个 BootROM 代码;

换句话来说,上电后,先接管系统的是 SoC 厂家的 BootROM,他要做些什么事情呢?初始化系统,CPU 的配置,关闭看门狗,初始化时钟,初始化一些外设(比如 USB Controller、MMC Controller,Nand Controller 等);

我们管这个 BootROM 叫做一级启动程序,而排在后面的就叫二级启动,这就是 SPL 名字的由来;

2、SPL 拿来干嘛

2.1、铺垫

为了讲清楚 spl 的用处,我需要先铺垫一点其他东西;

如果是大芯片(不是单片机),外挂了存储设备(eMMC、Nand、SDCard 等)和内存 RAM(SDRAM、DDR 等),通常情况下呢,我们要让系统跑起来,需要先烧写代码,这个烧写代码,其实是将可执行的二进制文件写到外部的存储设备上(eMMC、Nand、SD Card 等);系统上电启动的时候呢,去把他们读到内存中去执行;

前面我们说了,上电后,其实SoC 厂家自己的 BootROM,其他可执行的程序(u-boot、Kernel)都放(烧写)到了外部存储器是先去执行 上;

那么BootROM 的代码除了去初始化硬件环境以外,还需要去外部存储器上面,将接下来可执行的程序读到内存来执行;

既然是读到内存执行,那么这个内存可以不可以是我们板载的 DDR 呢?理论上是可以的,但是,SoC 厂家设计的 DDR 控制器呢,一般会支持很多种类型的 DDR 设备,并且会提供兼容性列表,SoC 厂家怎么可能知道用户 PCB 上到底用了哪种内存呢?所以,直接把外部可执行程序读到 DDR 显然是不太友好的,一般来说呢,SoC 都会做一个内部的小容量的 SRAM (又是成本),BootROM 将外部的可执行程序从存储器中读出来,放到 SRAM 去执行;

好了,现在我们引出了 SRAM,引出了 BootROM;

那么 BootROM 从具体哪个存储器读出二进制文件呢?SoC 厂家一般会支持多种启动方式,比如从 eMMC 读取,从 SDCard 读取,从 Nand Flash 读取等等;上电的时候,需要告诉它,它需要从什么样的外设来读取后面的启动二进制文件;

一般的设计思路是,做一组 Bootstrap Pin,上电的时候呢?BootROM 去采集这几个 IO 的电平,来确认要从什么样的外部存储器来加载后续的可执行文件;

比如呢,2 个 IO,2'b00 表示从 Nand 启动,2'b01 表示从 eMMC 启动,2'b10 表示从 SDCard 启动等等;

当 BootROM 读到这些值后,就会去初始化对应的外设,然后来读取后面要执行的代码;这些 IO 一般来说,会做成板载的拨码开关,用于调整芯片的启动方式;

这里,多说一句,读取烧写的二进制的时候呢,需要注意一些细节,比如,SoC 厂家告诉你,你需要先把 SDCard 初始化称为某种文件系统,然后把东西放进去才有效,之类的;因为文件系统是组织文件的方式,并不是裸分区;你按照 A 文件系统的方式放进去,然后 SoC 的 BootROM 也按照 A 文件系统的方式读出来,才能够达成一致;

2.2、spl

好了,铺垫得够多的了,这里我们回归主题:spl;

前面说了,BootROM 会根据 Bootstrap Pin 去确定从某个存储器来读可执行的二进制文件到 SRAM 并执行;理论上来说,这个二进制文件就可以是我们的 u-boot.bin 文件了;也就是 BootROM 直接加载 u-boot.bin;

理论上是这样的,但是这里有一个问题,就是 SRAM 很贵,一般来说,SoC 的片上 SRAM 都不会太大,一般 4KB、8KB、16KB...256KB不等;但是呢,u-boot 编译出来,却很大,好几百KB,放不下!

放不下怎么办?有两种办法:

1、放不下就放不下呗,BootROM 加载多少算多少;

2、做一个小一点的 boot 程序,先让 BootROM 加载这个小的程序,后面再由这个小 boot 去加载 u-boot;

比如,我们的 u-boot 有 300KB,SRAM 有 8KB,外部 DDR 1GB:

如果使用第一种方案的话,u-boot 的前面 8K 被加载进入 SRAM 执行,u-boot 被截断,我们就需要保证在 u-boot 的前 8KB 代码,把板载的 DDR 初始化好,把整个 u-boot 拷贝到 DDR,然后跳转到 DDR 执行;

第二种方案的话,我们做一个小的 u-boot ,这个 u-boot 就叫做 spl,它很小很小(小于SRAM大小),它先被 BootROM 加载到 SRAM 运行,那么这个 spl 要做什么事情呢?最主要的就是要初始化 DDR Controller,然后将真正的大 u-boot 从外部存储器读取到 DDR 中,然后跳转到大 u-boot;

如下图所示:

 

 我标记了一些东西:

先假设,我们的“货”,都已经放置到了外部存储器上,也就是绿色部分;

0、上电后,BootROM 开始执行,初始化时钟,关闭看门狗,关 Cache,关中断等等,根据 Bootstrap Pin 来确定启动设备,初始化外设;

1、使用外设驱动,从存储器读取 SPL;

---------------- 以上部分是 SoC 厂家的事情,下面是用户要做的事情 ----------------

2、SPL 被读到 SRAM 执行,此刻,控制权以及移交到我们的 SPL 了;

3、SPL 初始化外部 DDR;

4、SPL 使用驱动从外部存储器读取 u-boot 并放到 DDR;

5、跳转到 DDR 中的 u-boot 执行;

6、加载内核;

实际情况中,还需注意很多问题:

1、编译阶段的链接地址,是否需要地址无关?

2、SPL 的代码和 u-boot 的代码是否有重合的地方?如果有,是否意味着 SPL 执行过的,跳转到 u-boot 又要在执行一次?

3、具体情况下,需要配置哪些硬件?怎么配置?

这些问题,会在使用 spl 的时候,具体代码分析中逐个解答;请听下回分解;

### 解决 U-Boot 编译后 `u-boot.bin` 文件缺失或路径错误的方法 当遇到无法找到 `u-boot.bin` 或者其所在目录不正确的情况时,可以按照以下方法排查并解决问题。 #### 检查编译环境配置 确保开发环境中已安装所有必要的工具链和依赖项。对于特定版本的U-Boot源码包,如 u-boot-2014.04-tq210.zip 中提到的内容[^3],应当确认使用的交叉编译器与目标平台相匹配,并且环境变量设置无误。 #### 核实 Makefile 设置 查看项目中的顶层 Makefile以及板级支持包(BSP)对应的Makefile文件是否存在影响最终二进制输出位置的相关定义。例如,在某些旧版U-Boot中可能需要编辑类似这样的路径: ```makefile [root@localhost u-boot-2009.08]# vi board/samsung/gq2440/Makefile ``` 这表明应该检查对应于所用硬件型号的具体Makefile是否有特殊定制化需求[^4]。 #### 审视链接脚本 了解链接过程是如何决定可执行映像的位置非常重要。通常情况下,U-Boot 使用两个主要的链接描述文件来控制 SPL (Secondary Program Loader) 和主引导加载程序的行为: - 对于整个 U-Boot 映像 (`u-boot.bin`) ,会应用位于 arch/arm/cpu/u-boot.lds 的链接脚本; - 而针对早期启动阶段的小型加载器(`u-boot-spl.bin`) 则采用arch/arm/cpu/u-boot-spl.lds 来指定内存布局和入口地址。 如果发现生成的目标文件不符合预期,则可能是由于这些链接指令不当造成的。 #### 查找实际生成物 即使官方文档指出应在根目录下寻找 `u-boot.bin`,但在实际情况里可能会因为不同的构建选项而有所变化。尝试搜索整个工作区以定位该文件的实际存储地点: ```bash find . -name "u-boot*.bin" ``` 此命令可以帮助快速锁定任何带有 `.bin` 后缀并与 U-Boot 相关的文件。 #### 处理固定长度镜像的需求 有时为了适应特定设备的要求,还需要创建具有固定大小头信息的版本——即所谓的 `u-boot_crc.bin`. 此类操作涉及额外处理步骤,比如计算校验值并将原始映像嵌入到新的容器内[^2]: ```shell cp tools/mk_uboot_crc . ./mk_uboot_crc crc32 ./u-boot_crc.bin > ./u-boot_crc.bin.crc rm -f ./mk_uboot_crc ``` 上述流程展示了如何利用辅助工具制作带 CRC 校验的数据块。 ---
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值