第二章:启动模式与介质

做BootROM调试这些年,我接触最多的就是各种启动介质。说白了,芯片上电后第一件事就是找启动代码,但代码存在哪儿?怎么读?这里面门道可不少。

我记得刚入行那会儿,有个项目死活起不来,折腾了两天,最后发现是启动模式配置错了。嗯,从那以后,我养成了一个习惯——拿到板子先看启动模式引脚电平。

2.1 启动模式概述

芯片复位后,BootROM会先读取一组硬件引脚的电平状态,这些引脚通常叫BOOT_MODE[2:0]或类似的名字。根据这些引脚的电平组合,BootROM决定从哪个介质加载下一级启动代码。

你想想看,芯片本身不知道自己该从哪儿启动,全靠这些引脚告诉它。我见过不少工程师上来就调软件,结果发现是硬件上拉电阻焊错了。

核心要点:启动模式选择是BootROM的第一个关键决策点。模式配置错误,后面所有调试都是白费功夫。

2.2 NAND Flash启动

NAND Flash启动,说实话,是这里面最麻烦的一种。为什么?因为NAND Flash天生就有坏块,而且读取方式也特殊。

BootROM从NAND启动时,一般会做这几件事:

  • 初始化NAND控制器(时序参数要配准)
  • 读取第0块的数据(通常是4KB或8KB)
  • 校验ECC(错误纠正码)
  • 如果第0块坏了,自动跳到第1块

我在项目中遇到过最典型的问题:NAND时序参数配得太紧,导致高温下读取不稳定。后来我学乖了,时序参数都留20%的余量。

注意:NAND Flash的坏块管理是BootROM必须处理的。有些芯片的BootROM只做简单的坏块跳过,有些则支持完整的坏块表管理。选型时一定要看清楚。

2.3 NOR Flash启动

NOR Flash启动就简单多了。NOR Flash支持XIP(就地执行),也就是说CPU可以直接从NOR Flash里取指令执行,不需要先把代码拷贝到RAM里。

我记得有个项目用NOR Flash启动,BootROM只需要做两件事:

  1. 初始化NOR Flash接口(通常是SPI或并行接口)
  2. 跳转到NOR Flash的起始地址执行

说白了,NOR启动就是「映射-跳转」两步走。但要注意,NOR Flash的读取速度一般比RAM慢很多,所以通常只放启动代码,主程序还是要搬到RAM里跑。

小技巧:调试NOR启动时,可以用逻辑分析仪抓一下片选信号。如果片选信号正常但读不到数据,八成是时序匹配问题。

2.4 SD卡启动

SD卡启动在消费类产品里很常见。BootROM通过SDIO或SPI接口访问SD卡,读取特定扇区的内容。

SD卡启动的典型流程:

  • 初始化SDIO控制器
  • 发送CMD0复位命令
  • 发送CMD8检查SD卡版本
  • 发送ACMD41获取卡容量信息
  • 读取扇区0(MBR)或指定偏移的启动代码

我曾经踩过一个坑:某款SD卡在初始化时返回的OCR寄存器值不对,导致BootROM认为卡没准备好。后来发现是卡槽接触不良,电压检测引脚虚焊了。

2.5 USB启动

USB启动比较特殊,它不是为了量产,而是为了开发和调试用的。芯片通过USB枚举成一个设备,然后主机通过USB把启动代码下载到芯片的RAM里。

USB启动的流程:

  1. 初始化USB控制器(通常是USB Device模式)
  2. 等待USB主机枚举
  3. 接收主机发送的启动代码
  4. 将代码写入RAM并跳转执行

我个人习惯在USB启动时加一个超时机制。如果3秒内主机没连上来,就自动切换到下一个启动模式。这样既方便调试,又不耽误量产。

经验之谈:USB启动的调试信息最丰富,因为可以通过USB把日志传到主机上。我调试BootROM时,经常先用USB启动把基本功能调通,再切到其他介质。

2.6 SPI Flash启动

SPI Flash启动现在用得越来越多,因为它引脚少、体积小、成本低。BootROM通过SPI接口读取Flash里的数据。

SPI Flash启动的关键参数:

参数 说明 常见值
SPI时钟频率 决定读取速度 20MHz ~ 100MHz
SPI模式 CPOL和CPHA配置 Mode 0 或 Mode 3
读取命令 标准读还是快速读 0x03 或 0x0B
Dual/Quad模式 是否使用多线读取 标准/Dual/Quad

嗯,这里要注意:SPI Flash的读取命令和模式必须和Flash芯片匹配。我见过有人把Quad模式配成了标准模式,结果读出来的数据全是乱的。

2.7 eMMC启动

eMMC启动算是比较高级的启动方式了。eMMC内部集成了控制器和Flash,对外提供标准接口,BootROM不需要关心坏块管理这些事。

eMMC启动的步骤:

  • 初始化MMC控制器
  • 发送CMD1获取eMMC信息
  • 设置总线宽度(1位/4位/8位)
  • 设置时钟频率
  • 读取Boot分区或用户分区的启动代码

eMMC有个Boot分区,专门用来放启动代码。这个分区是只读的,防止意外擦除。我建议把BootROM的下一级代码放在Boot分区里,用户数据放在用户分区,这样隔离得清楚。

警告:eMMC的初始化时序比较严格,特别是上电后的等待时间。有些eMMC芯片需要等200ms才能响应第一个命令,BootROM里一定要加这个延时。

2.8 启动介质对比

我把这些启动介质的特性整理了一下,方便大家选型时参考:

介质 速度 复杂度 成本 适用场景
NOR Flash 中 低 高 小容量、XIP需求
NAND Flash 高 高 低 大容量存储
SD卡 中 中 低 消费电子、可插拔
USB 中 中 - 开发调试
SPI Flash 低-中 低 低 IoT、小封装
eMMC 高 中 中 手机、平板、工控

2.9 启动介质选择策略

实际项目中,芯片通常支持多种启动介质,并且有优先级顺序。BootROM会按照优先级依次尝试,直到某个介质启动成功。

我一般建议这样配置优先级:

  1. USB启动(调试阶段优先)
  2. SD卡/eMMC启动(量产阶段常用)
  3. SPI Flash/NOR Flash启动(备用方案)
  4. NAND Flash启动(最后尝试)

为什么会这样排?因为USB启动最灵活,适合开发调试。SD卡和eMMC速度够快,适合量产。SPI Flash和NOR Flash稳定可靠,适合做备份。NAND Flash最复杂,放在最后。

我的习惯:在产品开发阶段,我会把USB启动设为最高优先级。等软件稳定了,再改成从目标介质启动。这样万一刷坏了,还能通过USB救回来。

2.10 本章知识体系

下面这张图展示了启动介质选择的核心逻辑:

BootROM启动介质选择流程 芯片上电复位 读取BOOT_MODE引脚电平 模式选择 NAND Flash启动 NOR Flash / SPI Flash启动 SD卡 / eMMC启动 USB启动(调试模式) 起始 决策 启动介质 调试模式

这张图展示了BootROM启动介质选择的核心流程。芯片上电后,先读引脚电平,然后根据配置跳转到对应的启动介质。每个介质都有自己的一套初始化流程和读取协议。

做BootROM调试这么多年,我最大的体会是:启动介质这块,80%的问题出在初始化时序上,15%出在引脚配置上,只有5%是真正的代码逻辑问题。所以,当你遇到启动失败时,先别急着翻代码,拿示波器看看波形对不对。

嗯,启动介质这块就聊到这儿。每种介质都有它的脾气,摸透了就好办了。

可可精品资料库