1、BootROM概述:什么是BootROM、BootROM在系统启动中的角色、BootROM与BIOS/UEFI的区别

各位好,我是老周。做嵌入式固件这行十几年了,BootROM 算是我最早接触、也最常打交道的模块之一。今天咱们就聊聊这个“芯片上电后第一个跑起来的程序”——BootROM。

很多人觉得 BootROM 不就是个引导代码吗?其实没那么简单。你想想看,一颗芯片从出厂到最终运行你的应用程序,中间经历了什么?谁把它从“沉睡”中唤醒?谁去检查硬件是否正常?谁去决定从哪儿加载真正的固件?

嗯,这些脏活累活,全是 BootROM 干的。

1.1 什么是BootROM

BootROM,全称是 Boot Read-Only Memory。它是一段固化在芯片内部 ROM 中的启动代码。芯片一上电,CPU 复位后的第一条指令,就是从 BootROM 的入口地址开始执行。

说白了,BootROM 就是芯片的“基因”。它出厂就刻在硅片上,用户改不了。我遇到过不少刚入行的朋友,总想把 BootROM 也升级一下——别想了,那是硬件只读的。

核心特征:

  • 只读性:存储在 Mask ROM 或 OTP ROM 中,出厂后不可修改
  • 最先执行:CPU 复位向量直接指向 BootROM 区域
  • 硬件相关:与芯片架构、外设控制器紧密耦合
  • 尺寸极小:通常只有 4KB ~ 64KB,代码必须精简高效

我记得有一次调试一块新板子,上电后串口死活没输出。查了半天,发现是 BootROM 在初始化时钟之前就尝试配置了 UART——时序不对,外设根本没准备好。从那以后我养成了个习惯:拿到新芯片,第一件事就是看 BootROM 的初始化流程。

1.2 BootROM在系统启动中的角色

BootROM 在整个启动链中扮演什么角色?我习惯把它分成三个阶段来看。

第一阶段:硬件初始化

芯片上电瞬间,所有寄存器的值都是默认的。BootROM 要做的第一件事,就是让芯片“活过来”:

  • 配置 CPU 工作模式(比如从安全模式切换到特权模式)
  • 初始化关键外设:时钟、电源管理、内存控制器
  • 设置堆栈指针(SP),为 C 语言运行环境做准备

这里有个坑。我曾经在某款 ARM Cortex-M 芯片上遇到过:BootROM 默认把主频设得很低,导致后续从 SPI Flash 加载数据时速度极慢。后来我查了芯片手册才发现,BootROM 在初始化阶段会读一个硬件 strapping pin 来决定倍频系数——板子上那个电阻焊错了。

第二阶段:启动介质检测与加载

硬件初始化完成后,BootROM 就要去找真正的固件了。它会按照预设的优先级,依次尝试从不同的启动介质读取数据:

启动介质 典型场景 BootROM 检测方式
NAND Flash 嵌入式 Linux 系统 读取 ID 码,校验坏块标记
SPI NOR Flash MCU 应用、BIOS 存储 发送读命令,检查返回数据
eMMC/SD 卡 手机、平板、树莓派 发送 CMD0/CMD1,等待响应
USB/串口 开发调试、工厂烧录 检测总线上的下载请求
网络(TFTP/PXE) 无盘工作站、服务器 DHCP 广播,等待 BootP 响应

你可能会问:BootROM 怎么知道该从哪个介质启动?其实有两种方式:一是靠硬件引脚的电平组合(Boot Mode Pins),二是靠 BootROM 内部预设的优先级列表。我见过一个产品,量产时发现部分板子启动失败,最后定位到是 Boot Mode 引脚虚焊,导致 BootROM 读到了错误的电平组合。

第三阶段:安全校验与跳转

固件加载到 SRAM 或 DDR 后,BootROM 并不会直接跳过去执行。它会做一件至关重要的事——校验。

注意:现代芯片的 BootROM 几乎都内置了安全启动(Secure Boot)机制。BootROM 会用芯片内部固化的公钥,去验证加载进来的固件签名。如果签名校验失败,BootROM 会直接死循环或进入安全错误处理流程。

我曾经帮客户分析过一个启动失败的问题:他们的产品在低温环境下偶尔启动不了。我抓了 BootROM 的调试日志,发现是签名校验时读取 Flash 出现了位翻转——温度太低,Flash 的读取时序变了。后来我们在 BootROM 里加了重试机制,问题才解决。

校验通过后,BootROM 会做最后一步:清理自身痕迹(比如清零敏感数据),然后跳转到固件的入口地址。至此,BootROM 的使命完成。

1.3 BootROM与BIOS/UEFI的区别

很多做 PC 开发的朋友习惯把 BootROM 和 BIOS/UEFI 混为一谈。其实它们有本质区别。我整理了一个对比表,方便你理解:

对比维度 BootROM BIOS (Legacy) UEFI
存储位置 芯片内部 Mask ROM 主板 SPI Flash 主板 SPI Flash / eMMC
可修改性 不可修改(只读) 可升级(通过烧录工具) 可升级(通过 UEFI Capsule)
代码规模 4KB ~ 64KB 64KB ~ 512KB 数 MB ~ 数十 MB
硬件抽象 无抽象,直接操作寄存器 提供 INT 中断调用接口 提供 Protocol/Handle 驱动模型
启动介质支持 有限(由芯片厂商预定义) 支持 HDD、CD-ROM、USB 等 支持 GPT、网络、NVMe 等
安全机制 硬件级 Secure Boot 基本无(或依赖 TPM) Secure Boot + Measured Boot
典型应用 MCU、SoC、嵌入式系统 老旧 PC、工控机 现代 PC、服务器、ARM 服务器

说白了,BootROM 是芯片级别的“最小启动器”,而 BIOS/UEFI 是板级/系统级的“固件框架”。BootROM 只负责把芯片搞活、把下一级代码加载进来;BIOS/UEFI 则要负责枚举硬件、提供运行时服务、管理启动项。

我举个实际例子你就明白了。一块 ARM 开发板的上电流程是这样的:

  1. BootROM 初始化时钟和 DDR 控制器
  2. BootROM 从 SPI Flash 加载 SPL(Secondary Program Loader)到 SRAM
  3. SPL 初始化更复杂的外设(比如 eMMC 控制器)
  4. SPL 从 eMMC 加载 U-Boot 到 DDR
  5. U-Boot 加载 Linux 内核

你看,BootROM 只做了第 1、2 步。后面的 BIOS/UEFI 级别的活,是 SPL 和 U-Boot 干的。所以别把 BootROM 和 BIOS/UEFI 搞混了——它们根本不在一个层级上。

我的建议:如果你在调试启动问题,先搞清楚当前执行到哪一层了。BootROM 阶段出问题,通常串口都看不到输出;SPL 阶段出问题,能看到一些打印但卡住;U-Boot 阶段出问题,命令行能进去但加载内核失败。定位问题先分层,别一上来就怀疑内核。

好了,这一章的内容就这些。BootROM 的概念、角色、和 BIOS/UEFI 的区别,咱们都捋了一遍。下一章我会深入 BootROM 的校验机制——那才是咱们这门课的核心。

BootROM 在系统启动链中的位置 芯片上电 / 复位 BootROM 执行 硬件初始化 启动介质检测 安全校验 跳转到 SPL / 固件 BootROM 完成硬件初始化、介质检测和安全校验后,将控制权交给下一级启动代码 整个过程不可中断,不可调试(除非芯片提供调试接口)