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 开发板的上电流程是这样的:
- BootROM 初始化时钟和 DDR 控制器
- BootROM 从 SPI Flash 加载 SPL(Secondary Program Loader)到 SRAM
- SPL 初始化更复杂的外设(比如 eMMC 控制器)
- SPL 从 eMMC 加载 U-Boot 到 DDR
- U-Boot 加载 Linux 内核
你看,BootROM 只做了第 1、2 步。后面的 BIOS/UEFI 级别的活,是 SPL 和 U-Boot 干的。所以别把 BootROM 和 BIOS/UEFI 搞混了——它们根本不在一个层级上。
我的建议:如果你在调试启动问题,先搞清楚当前执行到哪一层了。BootROM 阶段出问题,通常串口都看不到输出;SPL 阶段出问题,能看到一些打印但卡住;U-Boot 阶段出问题,命令行能进去但加载内核失败。定位问题先分层,别一上来就怀疑内核。
好了,这一章的内容就这些。BootROM 的概念、角色、和 BIOS/UEFI 的区别,咱们都捋了一遍。下一章我会深入 BootROM 的校验机制——那才是咱们这门课的核心。