SPL Secondary Program Loader第二阶段程序加载器它是U-Boot 的精简迷你版只有几 KB~ 几十 KB作用初始化 DDR 内存 → 加载完整 U-Boot 到 DDR 中运行原因芯片内置 SRAM 极小通常只有 32KB/64KB/128KB放不下完整 U-Boot几百 KB一句话SPL 就是为了 “先点亮内存再加载大体积的完整 U-Boot”U-Boot SPL 完整启动流程第 0 阶段芯片上电 Boot ROM芯片厂商固化按下电源CPU 复位CPU 从芯片内置 Boot ROM开始执行这部分不是 U-Boot是芯片原厂写死的Boot ROM 做初始化最基础时钟读取启动引脚Boot Pin判断从哪里启动SD/eMMC/Flash/NAND从启动设备读取SPL到芯片内置 SRAM执行跳转到 SPL 入口点关键点Boot ROM 只负责加载 SPL不负责初始化 DDR第 1 阶段SPL 运行核心阶段SPL 进入运行它只干 3 件大事1. 最小化硬件初始化关闭看门狗配置系统时钟CPU/PLL初始化串口可选打印调试信息2. 初始化 DDR 内存SPL 最核心功能配置 DDR 控制器DDR 训练读写校准最终外部 DDR 可用3. 加载 完整 U-Boot 到 DDRSPL 从启动设备SD/NAND/eMMC/Flash读取u-boot.img/u-boot.bin并复制到DDR 内存地址如 0x800000004. 跳转到 完整 U-Boot 执行SPL 使命结束永远退出不再回来。第 2 阶段完整 U-Boot 运行从 DDR 中启动初始化所有外设扫描存储、网口、显示加载内核、设备树启动系统最直观的流程总结上电 → 芯片 Boot ROM固化 → 加载 SPL 到 内置 SRAM → 运行 SPL → 初始化时钟 → 初始化 DDR关键 → 加载 完整U-Boot 到 DDR → 跳转到 完整U-Boot → 加载内核 → 启动系统SPL 与 完整 U-Boot 的区别项目SPL完整 U-Boot体积极小KB 级别大几百 KB运行位置芯片内置 SRAM外部 DDR 内存核心任务初始化 DDR 加载 U-Boot加载内核、启动系统功能极简无命令行、无网口功能完整依赖不依赖 DDR必须依赖 DDRU-Boot SPL 完整启动流程图┌─────────────────────────────────────────────────────────────┐ │ 系统上电 / CPU 复位 │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SoC 内置 Boot ROM 代码 │ │ (芯片原厂固化不属于 U-Boot) │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 初始化最小时钟、复位模块 │ │ 2. 检测 Boot Pin 启动模式 (SD/eMMC/SPI-NAND/UART) │ │ 3. 从启动设备读取 SPL (u-boot-spl.bin) 到 **片内 SRAM** │ │ 4. 跳转到 SPL 的入口地址 (start.S) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL 阶段开始 │ ├───────────────────────────┬─────────────────────────────────┤ │ arch/arm/cpu/xxx/start.S (汇编入口) │ │ - 设置堆栈指针 SP │ │ - 关中断、关MMU、清BSS │ │ - 调用 C 语言入口函数 board_init_f() │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL board_init_f() │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 时钟初始化 (PLL/CLK) │ │ 2. 串口初始化 (可选打印debug) │ │ 3. 初始化 DDR 控制器 DDR 训练 (**SPL 最核心任务**) │ │ 4. 初始化启动设备接口 (MMC/SPI/NAND) │ │ 5. 设置全局数据、gd 结构体 │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL 加载完整 U-Boot │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 从启动设备读取 u-boot.img / u-boot.bin │ │ 2. 复制到 DDR 中指定地址 (CONFIG_SYS_TEXT_BASE) │ │ 3. 校验镜像头、大小、校验和 (如果有) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 跳转到完整 U-Boot │ │ jump_to_image_no_args() / bl31_entry() (ARM64) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 完整 U-Boot 正式启动 │ │ (DDR 已就绪开始初始化所有外设、命令行、引导内核) │ └─────────────────────────────────────────────────────────────┘Boot ROM 加载SPLBoot ROM 是 SoC 上电后执行的第一段固化代码核心是完成最小硬件初始化、识别启动介质、将 SPL 加载到片上 SRAM 并跳转执行为后续 DDR 初始化与完整 Bootloader 加载铺路。Boot ROM 加载 SPL 的完整流程通用 ARM SoC1. 上电复位与入口PC 硬编码芯片上电 / 复位CPU 程序计数器PC被强制指向Boot ROM 基地址如 ARMv7 常见0x00000000、ARMv8 常见0x00000000或0xFFFF0000。进入特权模式如 ARM SVC/EL3关闭中断、禁用 MMU/Cache设置最小栈SP。2. 最小硬件初始化Boot ROM 内部初始化核心时钟 / PLL让 CPU 与总线进入可工作频率。初始化片上 SRAMOCRAM/IRAM控制器使 SRAM 可读写DDR 此时未初始化无法使用。初始化启动介质控制器SPI/QSPI、eMMC/SD、NAND 等的基础时钟与引脚为读取 SPL 做准备。3. 读取启动模式Bootstrap Pins采样BOOT_MODE 引脚电平如 2 位BOOT[1:0]确定启动介质与顺序00SPI Nor Flash01eMMC10SD 卡11USB 下载MaskROM 模式用于救砖按芯片预设优先级扫描介质直到找到合法 SPL 镜像。4. 定位与读取 SPL 镜像在选定介质的固定偏移地址读取 SPLSD/eMMC通常从第 1 扇区0x200 字节偏移或0x40 扇区20KB开始。SPI Flash从0x00000000或分区头部读取。读取大小受SRAM 容量限制常见32KB/64KBSPL 必须小于该上限。读取方式按块 / 扇区读取通过 DMA 或 CPU 搬运到 SRAM。5. 镜像校验可选安全启动校验校验和Checksum或CRC32确保数据完整。若启用Secure Boot验证镜像数字签名RSA/ECC仅信任链合法才继续。6. 加载到 SRAM 并跳转执行将 SPL 二进制写入片上 SRAM 固定地址如 i.MX6ULL0x00900000RK33990xFF8C2000。设置SPL 入口点通常是镜像首地址或指定偏移。执行跳转指令如 ARMbx/bl将 CPU 控制权完全交给 SPLBoot ROM 使命结束。典型 SoC 示例i.MX6ULL / RK3399i.MX6ULLNXPBoot ROM 从 SD/eMMC0x1000064KB偏移读取 SPLu-boot-spl.bin。加载到OCRAM 0x00900000校验后跳转执行。SPL 初始化 DDR再加载 U-Boot 到 DDR0x87800000。RK3399瑞芯微Boot ROM 从 eMMC/SD0x40 扇区20KB读取 MiniLoaderSPL。加载到 SRAM0xFF8C2000校验通过后执行。MiniLoader 初始化 DDR 与安全固件ATF再加载 U-Boot。关键要点1. 为什么必须要有 SPL因为SRAM 容量限制片上 SRAM 仅几十 KB无法容纳完整 U-Boot数 MBSPL 是精简版引导器。DDR 未初始化Boot ROM 不负责 DDR 初始化板级 DDR 参数未知必须由 SPL 完成 DDR 配置为后续大镜像提供运行空间。信任链起点Boot ROM 是系统信任根Root of Trust仅加载并验证 SPL安全启动由此开始。所以必须用一个小体积的 SPL先初始化 DDR再加载大 U-Boot。2. SPL 从哪里来U-Boot 编译自动生成u-boot-spl.bin3. 启动文件结构SD 卡 / Flash 布局[Boot ROM 搜索位置] SPL → 完整 U-Boot → 环境变量 → 内核总结SPL 是 U-Boot 的 “前置迷你版”它唯一的使命就是在芯片极小的内置 SRAM 里运行初始化 DDR 内存然后把真正的完整 U-Boot 加载到 DDR 中执行。
U-Boot SPL
发布时间:2026/6/24 23:58:06
SPL Secondary Program Loader第二阶段程序加载器它是U-Boot 的精简迷你版只有几 KB~ 几十 KB作用初始化 DDR 内存 → 加载完整 U-Boot 到 DDR 中运行原因芯片内置 SRAM 极小通常只有 32KB/64KB/128KB放不下完整 U-Boot几百 KB一句话SPL 就是为了 “先点亮内存再加载大体积的完整 U-Boot”U-Boot SPL 完整启动流程第 0 阶段芯片上电 Boot ROM芯片厂商固化按下电源CPU 复位CPU 从芯片内置 Boot ROM开始执行这部分不是 U-Boot是芯片原厂写死的Boot ROM 做初始化最基础时钟读取启动引脚Boot Pin判断从哪里启动SD/eMMC/Flash/NAND从启动设备读取SPL到芯片内置 SRAM执行跳转到 SPL 入口点关键点Boot ROM 只负责加载 SPL不负责初始化 DDR第 1 阶段SPL 运行核心阶段SPL 进入运行它只干 3 件大事1. 最小化硬件初始化关闭看门狗配置系统时钟CPU/PLL初始化串口可选打印调试信息2. 初始化 DDR 内存SPL 最核心功能配置 DDR 控制器DDR 训练读写校准最终外部 DDR 可用3. 加载 完整 U-Boot 到 DDRSPL 从启动设备SD/NAND/eMMC/Flash读取u-boot.img/u-boot.bin并复制到DDR 内存地址如 0x800000004. 跳转到 完整 U-Boot 执行SPL 使命结束永远退出不再回来。第 2 阶段完整 U-Boot 运行从 DDR 中启动初始化所有外设扫描存储、网口、显示加载内核、设备树启动系统最直观的流程总结上电 → 芯片 Boot ROM固化 → 加载 SPL 到 内置 SRAM → 运行 SPL → 初始化时钟 → 初始化 DDR关键 → 加载 完整U-Boot 到 DDR → 跳转到 完整U-Boot → 加载内核 → 启动系统SPL 与 完整 U-Boot 的区别项目SPL完整 U-Boot体积极小KB 级别大几百 KB运行位置芯片内置 SRAM外部 DDR 内存核心任务初始化 DDR 加载 U-Boot加载内核、启动系统功能极简无命令行、无网口功能完整依赖不依赖 DDR必须依赖 DDRU-Boot SPL 完整启动流程图┌─────────────────────────────────────────────────────────────┐ │ 系统上电 / CPU 复位 │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SoC 内置 Boot ROM 代码 │ │ (芯片原厂固化不属于 U-Boot) │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 初始化最小时钟、复位模块 │ │ 2. 检测 Boot Pin 启动模式 (SD/eMMC/SPI-NAND/UART) │ │ 3. 从启动设备读取 SPL (u-boot-spl.bin) 到 **片内 SRAM** │ │ 4. 跳转到 SPL 的入口地址 (start.S) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL 阶段开始 │ ├───────────────────────────┬─────────────────────────────────┤ │ arch/arm/cpu/xxx/start.S (汇编入口) │ │ - 设置堆栈指针 SP │ │ - 关中断、关MMU、清BSS │ │ - 调用 C 语言入口函数 board_init_f() │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL board_init_f() │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 时钟初始化 (PLL/CLK) │ │ 2. 串口初始化 (可选打印debug) │ │ 3. 初始化 DDR 控制器 DDR 训练 (**SPL 最核心任务**) │ │ 4. 初始化启动设备接口 (MMC/SPI/NAND) │ │ 5. 设置全局数据、gd 结构体 │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ SPL 加载完整 U-Boot │ ├───────────────────────────┬─────────────────────────────────┤ │ 1. 从启动设备读取 u-boot.img / u-boot.bin │ │ 2. 复制到 DDR 中指定地址 (CONFIG_SYS_TEXT_BASE) │ │ 3. 校验镜像头、大小、校验和 (如果有) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 跳转到完整 U-Boot │ │ jump_to_image_no_args() / bl31_entry() (ARM64) │ └───────────────────────────┬─────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 完整 U-Boot 正式启动 │ │ (DDR 已就绪开始初始化所有外设、命令行、引导内核) │ └─────────────────────────────────────────────────────────────┘Boot ROM 加载SPLBoot ROM 是 SoC 上电后执行的第一段固化代码核心是完成最小硬件初始化、识别启动介质、将 SPL 加载到片上 SRAM 并跳转执行为后续 DDR 初始化与完整 Bootloader 加载铺路。Boot ROM 加载 SPL 的完整流程通用 ARM SoC1. 上电复位与入口PC 硬编码芯片上电 / 复位CPU 程序计数器PC被强制指向Boot ROM 基地址如 ARMv7 常见0x00000000、ARMv8 常见0x00000000或0xFFFF0000。进入特权模式如 ARM SVC/EL3关闭中断、禁用 MMU/Cache设置最小栈SP。2. 最小硬件初始化Boot ROM 内部初始化核心时钟 / PLL让 CPU 与总线进入可工作频率。初始化片上 SRAMOCRAM/IRAM控制器使 SRAM 可读写DDR 此时未初始化无法使用。初始化启动介质控制器SPI/QSPI、eMMC/SD、NAND 等的基础时钟与引脚为读取 SPL 做准备。3. 读取启动模式Bootstrap Pins采样BOOT_MODE 引脚电平如 2 位BOOT[1:0]确定启动介质与顺序00SPI Nor Flash01eMMC10SD 卡11USB 下载MaskROM 模式用于救砖按芯片预设优先级扫描介质直到找到合法 SPL 镜像。4. 定位与读取 SPL 镜像在选定介质的固定偏移地址读取 SPLSD/eMMC通常从第 1 扇区0x200 字节偏移或0x40 扇区20KB开始。SPI Flash从0x00000000或分区头部读取。读取大小受SRAM 容量限制常见32KB/64KBSPL 必须小于该上限。读取方式按块 / 扇区读取通过 DMA 或 CPU 搬运到 SRAM。5. 镜像校验可选安全启动校验校验和Checksum或CRC32确保数据完整。若启用Secure Boot验证镜像数字签名RSA/ECC仅信任链合法才继续。6. 加载到 SRAM 并跳转执行将 SPL 二进制写入片上 SRAM 固定地址如 i.MX6ULL0x00900000RK33990xFF8C2000。设置SPL 入口点通常是镜像首地址或指定偏移。执行跳转指令如 ARMbx/bl将 CPU 控制权完全交给 SPLBoot ROM 使命结束。典型 SoC 示例i.MX6ULL / RK3399i.MX6ULLNXPBoot ROM 从 SD/eMMC0x1000064KB偏移读取 SPLu-boot-spl.bin。加载到OCRAM 0x00900000校验后跳转执行。SPL 初始化 DDR再加载 U-Boot 到 DDR0x87800000。RK3399瑞芯微Boot ROM 从 eMMC/SD0x40 扇区20KB读取 MiniLoaderSPL。加载到 SRAM0xFF8C2000校验通过后执行。MiniLoader 初始化 DDR 与安全固件ATF再加载 U-Boot。关键要点1. 为什么必须要有 SPL因为SRAM 容量限制片上 SRAM 仅几十 KB无法容纳完整 U-Boot数 MBSPL 是精简版引导器。DDR 未初始化Boot ROM 不负责 DDR 初始化板级 DDR 参数未知必须由 SPL 完成 DDR 配置为后续大镜像提供运行空间。信任链起点Boot ROM 是系统信任根Root of Trust仅加载并验证 SPL安全启动由此开始。所以必须用一个小体积的 SPL先初始化 DDR再加载大 U-Boot。2. SPL 从哪里来U-Boot 编译自动生成u-boot-spl.bin3. 启动文件结构SD 卡 / Flash 布局[Boot ROM 搜索位置] SPL → 完整 U-Boot → 环境变量 → 内核总结SPL 是 U-Boot 的 “前置迷你版”它唯一的使命就是在芯片极小的内置 SRAM 里运行初始化 DDR 内存然后把真正的完整 U-Boot 加载到 DDR 中执行。