U-Boot Bring Up:有 SPL 与无 SPL 的启动流程深度解析

支持作者新书,点击京东购买《Yocto项目实战教程:高效定制嵌入式Linux系统》


U-Boot Bring Up:有 SPL 与无 SPL 的启动流程深度解析

前言

在嵌入式 Linux 系统开发、BSP 适配及新平台 bring-up 过程中,Bootloader 的启动流程往往决定了整个系统移植和硬件支持的复杂度。U-Boot 作为当前主流的开源 Bootloader,其启动流程又分为带 SPL(Secondary Program Loader)不带 SPL两种模式。不同方案在硬件要求、启动机制、代码结构、调试思路等方面存在明显区别。

本文将围绕这一主题,结合典型平台结构、流程图、配置文件、核心代码段,深入对比两种方案的适用场景、实现细节及工程实践建议,帮助读者理解底层差异,并能在项目中合理选择。


一、基础概念与总体启动流程

1.1 Bootloader 在嵌入式系统中的角色

  • 初始化硬件:如时钟、内存、串口、存储、网络等。
  • 加载/引导操作系统:通常是 Linux 内核,并传递启动参数、设备树等必要信息。
  • 提供调试与维护功能:如环境变量配置、固件升级、网络引导、烧写命令等。

1.2 U-Boot 典型启动阶段

以 ARM Cortex-A SoC(如 NXP i.MX6/8, Allwinner, Rockchip, STM32MP1 等)为例,完整启动链路如下:
在这里插入图片描述

有 SPL 的启动流程
BootROM (SoC内部固件) → SPL (精简U-Boot) → U-Boot (完整版) → Linux Kernel → RootFS → User Application
无 SPL 的启动流程
BootROM (SoC内部固件) → U-Boot (完整版) → Linux Kernel → RootFS → User Application

在这里插入图片描述

1.3 BootROM 与 SPL 的职责区别

  • BootROM:不可更改,由芯片原厂烧录在 SoC 内部,只负责最基础的硬件初始化和“从外部介质加载 bootloader 到 SRAM/DRAM 并运行”。
  • SPL:U-Boot 的精简版,用于解决“内部SRAM容量有限,无法一次加载完整版 U-Boot”时的硬件初始化需求(如 DDR、时钟、简单外设)。
  • 完整版 U-Boot:具备命令行、丰富外设/协议栈支持,可做升级、调试、启动内核等。

二、带 SPL 与无 SPL 的根本差异

2.1 SPL 设计的核心动机

SPL 解决的核心问题:SoC 上电后,可用的 SRAM 极其有限,无法直接放下大体积的 U-Boot
因此,必须先用极小的 SPL 初始化 DDR,之后将完整版 U-Boot 从外部介质加载到 DDR,再切换到 U-Boot 运行。

场景举例:
  • 典型 Cortex-A9/A53/A72 SoC,SRAM 只有 32KB/64KB/128KB,而完整版 U-Boot 动辄数百 KB 甚至上 MB。
  • 需要复杂 DRAM 初始化脚本,BootROM 能力有限。

2.2 无 SPL 方案的条件

  • SoC 内部 SRAM 或 BootROM 能直接完成 DDR 初始化。
  • BootROM 能直接从存储加载大容量 U-Boot 到 DDR 并运行。
  • U-Boot 镜像尺寸可以接受(如 NOR flash 启动、小型芯片/简单板卡)。
场景举例:
  • 早期的 ARM9、ARM11、部分 Cortex-M4/M7,以及 MCU 级应用,内存需求不高。
  • 使用 NOR Flash,直接映射到地址空间,无需分段加载。
  • BootROM 足够灵活/支持的 SoC(如部分 Allwinner、Rockchip、早期NXP平台等)。

三、详细启动流程对比

3.1 有 SPL 启动流程详解

  1. BootROM 执行
    SoC 上电后,BootROM 按固定顺序检测外部存储(SD/eMMC/NAND/NOR/USB等),找到并加载 SPL 到 SRAM。

  2. SPL 阶段

    • 初始化必要硬件(主要是时钟/DDR)。
    • 极简驱动,仅包含板级初始化和加载U-Boot代码的功能。
    • 加载完整 U-Boot 镜像到 DDR。
  3. 跳转至 U-Boot
    SPL 跳转到 DDR 内的 U-Boot 入口,后者接管控制权。

  4. U-Boot 主阶段

    • 初始化更丰富的外设。
    • 提供 CLI/网络/升级/调试等功能。
    • 加载和启动 Linux 内核。
  5. 操作系统启动

核心代码片段(SPL 入口流程示例):
void board_init_f(ulong dummy)
{
    // 最小化硬件初始化
    arch_cpu_init();
    spl_init();
    dram_init();
    // 读取并加载主 U-Boot
    spl_load_image();
    jump_to_uboot();
}
SPL 配置(典型 Kconfig/defconfig)
CONFIG_SPL=y
CONFIG_SPL_FRAMEWORK=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y

3.2 无 SPL 启动流程详解

  1. BootROM 执行
    SoC 上电后,BootROM 直接从外部存储加载完整 U-Boot 镜像到内存(一般是 DDR)并执行。

  2. U-Boot 阶段

    • U-Boot 自行初始化全部硬件(包含 DDR)。
    • 后续流程同上:提供 CLI、升级、内核引导等功能。
  3. 操作系统启动

核心代码片段(U-Boot 入口流程示例):
void board_init_f(ulong dummy)
{
    // 直接初始化所有硬件
    arch_cpu_init();
    dram_init();
    peripheral_init();
    // 进入命令行或直接启动内核
    main_loop();
}
配置特征
  • .config 文件里无 CONFIG_SPL 相关选项。
  • 编译输出只有单个 U-Boot 镜像,无 u-boot-spl 文件。

四、硬件与软件层面的适用分析

4.1 带 SPL 的优势和适用场景

  • 适合中高端 SoC,SRAM 远小于 U-Boot 镜像体积。
  • 支持复杂的板级初始化需求(如多片 DDR、PMIC、丰富外设)。
  • 支持多存储介质和更灵活的启动策略。
  • 可拆分初始化流程,有利于分阶段调试和维护。

4.2 无 SPL 的优势和适用场景

  • 平台简单、硬件初始化需求低,BootROM 或 NOR Flash 直映射即可。
  • 启动速度快,代码复杂度低,适用于量产型、成本敏感的设计。
  • 有利于初学者和小型项目快速上手。

五、开发实践建议

5.1 如何判断自己平台需要 SPL?

  • 检查 SoC 文档“BootROM 支持的最大加载大小”“上电后可用的 SRAM/DRAM 初始化流程”。
  • 若 U-Boot 体积超过 BootROM 一次性可加载容量,必须引入 SPL。
  • 若平台/芯片厂商提供的参考 U-Boot 都有 SPL 分段,说明其硬件需要这种启动分阶段。

5.2 编译与适配流程要点

  • 有 SPL:编译时会生成 u-boot-spl/u-boot-spl.bin,同时 u-boot/u-boot.bin/elf,烧录脚本须注意 SPL 与主镜像分区、拼接位置等。
  • 无 SPL:只有主镜像直接烧录,启动配置/烧写脚本更简单。

5.3 调试和移植建议

  • 有 SPL 时遇到 DDR 问题,建议优先只修改/调试 SPL,主 U-Boot 尽量保持稳定。
  • 无 SPL 时,所有初始化和调试均集中于 U-Boot 代码,调试窗口更大但也更易出错。

六、关键问答与实战案例

Q1:我怎么判断我的平台当前用不用 SPL?

  • .config/defconfig 是否有 CONFIG_SPL=y,或者编译输出目录有无 u-boot-spl
  • 查阅官方 BSP 用户手册,查看推荐的启动分段方案。

Q2:什么情况下可以把 SPL 去掉,只用 U-Boot?

  • 硬件初始化极其简单,BootROM 能直接装载主 U-Boot 并执行(如 NOR Flash 映射)。
  • 平台定制需求低,工程团队能确认无后遗症。

Q3:SPL 和 U-Boot 如何协作传递信息?

  • SPL 可通过 RAM、寄存器、中转地址等方式,传递板级信息、环境参数、校验结果。
  • SPL 失败可直接回退或报错重启,利于早期调试。

Q4:如果引导流程挂死,如何排查是 SPL 还是 U-Boot 的问题?

  • 观察串口输出:SPL 阶段 log 是否输出,若 SPL 输出正常则重点排查 U-Boot;否则需定位 SPL 问题。
  • 可以定制 SPL 提示灯/蜂鸣器等硬件动作,辅助区分。

七、结语

带 SPL 与不带 SPL 的 U-Boot 启动架构,是嵌入式 SoC bring-up 的两个关键模式。正确理解其差异,有助于做出合理的系统架构决策、BSP移植和调试,也有助于快速定位启动链路的瓶颈。对于中高端 SoC,新项目建议优先采用 SPL 分段启动模式,以获得更好的灵活性和兼容性。



支持作者新书,点击京东购买《Yocto项目实战教程:高效定制嵌入式Linux系统》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值