2. 嵌入式启动基础

在讨论 U-Boot 之前,必须先理解一个更底层的问题:处理器从按下复位键到执行第一条用户代码,中间究竟发生了什么。很多板级调试问题——串口无输出、启动卡死、镜像校验失败、启动介质切换无效——本质上都发生在 U-Boot 之前,属于“启动链前段”的问题。本节围绕上电复位流程、BootROM 的作用、启动介质类型以及典型启动阶段划分展开,为后续分析 U-Boot SPL、TPL 与主 U-Boot 的衔接建立基础。

一、上电复位流程:从电压稳定到取指

处理器上电并不是“一通电就执行程序”。电源管理芯片(PMIC)或分立电源电路先建立各路电压,复位管理单元等待电源稳定、时钟稳定后释放复位信号。复位释放的瞬间,CPU 内部寄存器被置为确定的复位值,程序计数器(PC)被强制指向一个固定的复位向量地址。这个地址通常位于芯片内部 ROM 或 Flash 映射区,而不是外部 DDR,因为此时 DDR 尚未初始化,无法作为代码运行空间。

复位流程可以概括为几个关键动作:电源建立与稳定、复位信号释放、时钟树初始化、CPU 取复位向量、执行芯片固化的启动代码。对于多核处理器,通常由主核(如 ARM 的 CPU0)先执行,其他核处于等待或由主核后续唤醒。理解这一点很重要:调试时如果发现“只有某个核没起来”,往往不是 U-Boot 的问题,而是复位释放或核间同步配置的问题。

关键结论:复位向量地址、时钟初始化、DDR 初始化时机,是启动链前段最容易被忽视却最常导致“无输出”的三个点。

二、BootROM 的作用:芯片内的第一段代码

BootROM 是芯片厂商在硅片内部固化的一段只读代码,用户无法修改。它的核心职责是:在没有任何外部存储可用的情况下,完成最基本的硬件初始化,并按预定策略从启动介质中加载下一阶段代码。BootROM 通常包含以下能力:

  • 初始化启动所需的最小外设控制器,如 SPI、SD/eMMC、NAND、USB、UART 等;
  • 读取启动模式引脚(Boot Mode Strap)或熔丝位,确定启动介质优先级;
  • 从选定介质中读取头部信息,校验签名、校验和或镜像格式;
  • 将下一阶段镜像加载到片内 SRAM 或已初始化的 DDR 中;
  • 跳转到加载地址执行,并把控制权交给 SPL 或二级引导程序。

BootROM 的行为由芯片决定,但启动顺序通常可通过引脚、eFuse 或 BootROM 配置字调整。例如 Allwinner、Rockchip、NXP i.MX、TI AM335x 等平台都提供不同的启动介质优先级。调试时若发现“从 SD 卡启动失败但从 USB 可以”,往往说明 BootROM 的启动模式选择或介质探测顺序与预期不一致。

三、启动介质类型与选择逻辑

嵌入式系统常见的启动介质包括 SPI NOR、SPI NAND、并行 NAND、eMMC、SD 卡、USB、UART、以太网等。不同介质的访问方式、初始化复杂度、可靠性和成本差异很大。BootROM 一般按固定优先级依次尝试,直到某个介质上找到合法镜像为止。

启动介质典型接口特点常见用途
SPI NORSPI/QSPI可直接映射执行,容量小,可靠性高小型系统、BootROM 后直接运行
SPI NANDSPI成本低,容量较大,需坏块管理中低端嵌入式产品
eMMCMMC/SDIO容量大,速度快,支持分区主流消费与工业设备
SD 卡SDIO/SPI可插拔,便于开发调试开发板、量产烧录
USB/UARTUSB/串口无需外部存储,依赖主机工具工厂烧录、救砖

选择启动介质时,需要同时考虑 BootROM 支持能力、硬件引脚配置、镜像格式和烧录方式。例如某些芯片的 BootROM 只支持从 eMMC 的 boot 分区读取,而不支持 user 分区;某些平台要求 SD 卡镜像必须带特定头部。忽略这些约束,就会出现“镜像明明写进去了却启动不了”的情况。

四、典型启动阶段划分:从 BootROM 到操作系统

为了便于分析和调试,通常把嵌入式启动链划分为若干阶段。一个典型的 ARM 嵌入式平台启动阶段如下:

  1. BootROM 阶段:芯片固化代码,完成最小初始化并加载 SPL。
  2. SPL/TPL 阶段:在片内 SRAM 中运行,初始化 DDR、时钟和必要外设,加载主 U-Boot。
  3. 主 U-Boot 阶段:运行在 DDR 中,提供命令行、驱动模型、环境变量和操作系统加载能力。
  4. 内核与根文件系统阶段:U-Boot 加载 Linux 内核、设备树和根文件系统,跳转执行。

下面用一张信号链/阶段关系图展示从复位到内核的完整路径,图中标注了各阶段运行位置、关键动作和典型输出。

嵌入式启动链:从复位到内核的典型阶段 上电复位 电源稳定 时钟释放 BootROM 片内固化代码 选择启动介质 SPL / TPL 片内 SRAM 运行 初始化 DDR 主 U-Boot DDR 中运行 命令行/驱动模型 内核 设备树 根文件系统 运行位置与关键动作 BootROM:片内 ROM,不可修改,负责介质探测与镜像校验;SPL:片内 SRAM,初始化 DDR 与时钟;主 U-Boot:DDR,加载内核;内核:接管系统。 典型串口输出:BootROM 无输出 → SPL 打印 “U-Boot SPL” → 主 U-Boot 打印 “U-Boot 20xx.xx” → 内核启动日志。 启动介质优先级示例 1. eMMC boot 分区 2. SD 卡 3. USB / UART 下载模式 常见卡点 DDR 初始化失败 → SPL 无输出 镜像头部错误 → BootROM 跳过 启动引脚配置错误 → 介质不匹配 调试建议 先确认 BootROM 是否识别介质 再确认 SPL 是否打印 DDR 信息 最后检查 U-Boot 环境与内核加载

五、案例与误区复盘

某工业网关板使用 i.MX6ULL,设计为从 eMMC 启动。量产时发现部分板卡上电后串口无任何输出,但同一镜像写入 SD 卡可以正常启动。排查后发现,eMMC 的 boot 分区未烧录 SPL,而 BootROM 默认优先从 eMMC boot 分区读取,读取失败后并未回退到 SD 卡,导致“无输出”。解决方法是使用 mfgtool 或 dd 命令将 SPL 写入 eMMC boot 分区,或调整启动引脚优先级。

另一个常见误区是把 U-Boot 主镜像直接烧到启动介质偏移 0 处,而忽略了 SPL 的头部要求。BootROM 通常只识别带特定 IVT、Boot Header 或校验和的镜像,裸 U-Boot 二进制不会被加载。正确做法是使用厂商提供的 mkimage、imx-mkimage 或 build 脚本生成完整启动镜像。

排障顺序建议:先看 BootROM 是否输出(部分芯片无输出属正常),再看 SPL 是否有打印,最后看主 U-Boot 是否进入命令行。不要一上来就怀疑 U-Boot 配置。
# 典型启动日志片段
U-Boot SPL 2023.04 (Jan 10 2024 - 10:22:31)
Trying to boot from MMC1
U-Boot 2023.04 (Jan 10 2024 - 10:22:31 +0800)
CPU:   i.MX6ULL 792 MHz
DRAM:  512 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK

掌握本节内容后,再分析 U-Boot 启动链时,就能清楚地区分“BootROM 没找到镜像”“SPL 没初始化好 DDR”“主 U-Boot 没加载内核”这三类问题,从而快速定位故障阶段,而不是在 U-Boot 源码中盲目搜索。