第一章:BootROM与硬件初始化

按下电源键的那一刻,手机里到底发生了什么?

很多人觉得,开机就是“啪”一下亮了。但说实话,这背后是一套极其严谨的硬件接力赛。今天我们就从最底层开始,看看CPU是怎么从“死寂”中醒过来的。

1.1 复位向量:CPU的第一口奶

按下电源键,PMIC(电源管理芯片)开始给各个模块供电。电压稳定后,硬件会拉低RESET引脚,然后释放——这就是复位信号。

CPU复位后,它做的第一件事是什么?

去一个固定的地址取指令。这个地址,就是复位向量(Reset Vector)。

以ARM Cortex-A系列为例,复位向量通常是0x000000000xFFFF0000。具体是哪个,取决于硬件设计。我见过不少工程师在这里栽跟头——板子焊好了,死活跑不起来,最后发现是复位向量映射错了。

嗯,这里要注意:复位向量里存的不是代码,而是一条跳转指令。它指向BootROM的入口地址。

关键点:复位向量是CPU执行的第一个指令地址。它通常位于芯片内部ROM中,不可修改。

1.2 BootROM:芯片出厂自带的“小系统”

BootROM是固化在芯片内部的一块只读存储器。你买到的每一颗芯片,里面都已经烧录好了这段代码。

它的任务很简单:找到并加载Bootloader

但问题来了——Bootloader可能放在NAND Flash、eMMC、UFS,甚至SD卡里。BootROM怎么知道该从哪读?

答案是:启动模式检测

CPU会去检测几个特定的GPIO引脚电平,这些引脚在硬件设计时就定好了。比如:

  • 电平组合A → eMMC启动
  • 电平组合B → UART下载模式
  • 电平组合C → USB下载模式

我在做一款平板时,就遇到过启动模式引脚被拉错的情况。结果BootROM一直尝试从eMMC加载,但eMMC根本没焊……折腾了两天才发现是原理图有个电阻贴错了。

1.3 加载与校验:信任链的第一环

确定启动设备后,BootROM开始读取Bootloader的第一阶段(通常是SPL或PBL)。

但这里有个安全问题:如果Bootloader被篡改了怎么办?

所以BootROM会做签名校验

流程大致是这样的:

  1. 从存储设备读取Bootloader头部
  2. 提取签名信息和公钥哈希
  3. 用芯片内置的OTP(一次性可编程)密钥进行验证
  4. 校验通过 → 跳转到Bootloader执行
  5. 校验失败 → 进入下载模式或死循环

避坑指南:我曾经在量产阶段遇到一批芯片无法开机,排查后发现是OTP区域写入的密钥和Bootloader签名不匹配。从那以后,我每次做密钥烧录都会做三次交叉验证。

1.4 硬件初始化:让外设“活过来”

BootROM在跳转之前,还会做一些最基本的硬件初始化。说白了,就是让CPU能跟外界通信。

初始化模块 作用
系统时钟 设置CPU主频、总线频率
SRAM控制器 初始化内部SRAM,作为栈空间
存储控制器 配置eMMC/NAND接口时序
基本GPIO 设置启动模式引脚、状态指示灯

你想想看,这些初始化代码是固化在ROM里的,没法改。所以芯片原厂必须保证它足够通用,能适配各种硬件设计。这也是为什么BootROM代码通常很精简——它只做“必须做”的事。

1.5 从BootROM到Bootloader的交接

校验通过后,BootROM会把控制权交给Bootloader。怎么交?

很简单:跳转到Bootloader在SRAM中的入口地址

这时候,CPU的PC指针直接指向Bootloader的第一条指令。BootROM的任务就结束了。

但这里有个细节:BootROM在跳转前,会清理掉自己的栈和临时数据。为什么?

为了安全。防止Bootloader通过残留数据反推BootROM的逻辑。嗯,芯片厂商在这方面考虑得很周全。

注意事项:BootROM和Bootloader之间的接口约定是固定的。比如参数传递寄存器、栈指针位置等。如果你自己写Bootloader,必须严格遵守这些约定,否则一启动就崩。

1.6 小结

从按下电源键到BootROM执行完毕,整个过程通常在几百毫秒内完成。但就是这短短的时间,完成了:

  • CPU复位与取指
  • 启动模式检测
  • Bootloader加载与签名校验
  • 基本硬件初始化
  • 控制权交接

说白了,BootROM就是整个启动流程的“守门人”。它虽然小,但责任重大。我见过不少系统启动问题,追根溯源都出在这一阶段——要么是硬件设计没按芯片手册来,要么是签名校验配置错了。

下一章,我们会深入Bootloader,看看它又是怎么把Linux内核请出来的。