启动模式与介质:你的芯片怎么知道该从哪启动?

芯片上电后,第一件事就是找代码来执行。但问题是——代码放在哪?是焊在板子上的 NOR Flash,还是贴片 eMMC,又或者是调试时临时插的 SD 卡?

BootROM 自己不会猜。它得靠一套固定的机制来确定启动源。这套机制,就是我们今天要聊的启动模式选择与启动介质。

我早年做第一款量产产品时,就栽过跟头。板子回来死活不跑,查了两天才发现——Boot Mode 电阻虚焊,芯片一直以为自己在等 UART 下载。嗯,从那以后,我对启动模式引脚的设计检查就格外上心。

主流启动介质:各有各的脾气

不同的启动介质,在速度、容量、接口、可靠性上差异很大。选型时不能只看成本,还得看 BootROM 是否原生支持。

介质 接口类型 典型容量 读速度 是否支持XIP BootROM 常见支持
NOR Flash SPI / Parallel 1MB ~ 64MB 中 ✅ 是 几乎全支持
NAND Flash ONFI / Raw NAND 128MB ~ 8GB 高(连续读) ❌ 否 需搬运代码到SRAM
eMMC MMC / SDIO 4GB ~ 128GB 高 ❌ 否 需分区引导
SD 卡 SD / SPI 2GB ~ 32GB 中高 ❌ 否 调试阶段常用
UART UART 无 极低(115200bps) ❌ 否 下载模式
USB USB 2.0/3.0 无 高 ❌ 否 下载/DFU模式

关键区别:NOR Flash 支持 XIP(Execute In Place),CPU 可以直接在 Flash 上取指运行。NAND、eMMC、SD 卡都不行——BootROM 必须先把一小段引导代码搬到内部 SRAM,再跳过去执行。这个搬运过程,就是所谓的 Boot Loader 第一阶段。

NOR Flash:最省心的启动伙伴

我个人最喜欢 NOR Flash 做启动介质。为什么?因为它简单。

  • XIP 特性:CPU 复位后直接映射到地址 0x0,取复位向量,开跑。不需要搬运,不需要初始化 DRAM。
  • 可靠性高:位翻转概率极低,几乎不需要 ECC。
  • 接口成熟:SPI NOR 只需要 4~6 根线,PCB 布局非常友好。

但 NOR 也有短板——容量做不大,价格贵。你想想看,现在一个 16MB 的 SPI NOR 就要一两块钱,而同样价格的 NAND 能给你 1GB。所以 NOR 通常只放 BootROM 和第一级引导,真正的固件还是放在 NAND 或 eMMC 里。

实战经验:我在一个 IoT 项目里用过 W25Q128(16MB SPI NOR)同时放 Bootloader 和 Application。因为固件只有 6MB,完全够用。省掉了一颗 NAND 的成本和 ECC 校验的麻烦。如果你的固件小于 16MB,NOR 是性价比很高的选择。

NAND Flash:容量大,但坑也多

NAND 的启动流程比 NOR 复杂不少。BootROM 需要做这几件事:

  1. 初始化 NAND 控制器(时序参数、IO 配置)
  2. 读取 NAND 的 ID,确认型号
  3. 跳过坏块(Bad Block),找到有效的 Boot Image
  4. 将代码从 NAND 搬运到内部 SRAM(通常 4KB ~ 64KB)
  5. 校验 ECC,确保数据正确
  6. 跳转到 SRAM 执行

这里有个容易踩的坑——坏块管理。NAND 出厂就有坏块,而且使用过程中还会产生新的坏块。BootROM 通常只扫描前几个块(比如 Block 0 ~ Block 3),如果这些块恰好都是坏块,芯片就启动不了。

我曾经遇到过一批 NAND,Block 0 在出厂时就是坏块,但产线烧录工具没做坏块跳过,直接把 Boot Image 写到了 Block 0。结果 30% 的板子无法启动。排查后发现,BootROM 只检查 Block 0,发现是坏块就直接放弃了。解决方案是:烧录时强制写到 Block 1,并在 Block 0 写入一个跳转标记。

eMMC:现代嵌入式的主流选择

eMMC 内部集成了 NAND 和控制器,坏块管理、ECC、磨损均衡都由芯片自己搞定。对 BootROM 来说,eMMC 就像一个黑盒子——发命令,读数据,简单粗暴。

eMMC 的启动流程通常走 Boot Partition 模式:

  • eMMC 内部有专门的 Boot Area Partition(通常 512KB ~ 4MB)
  • BootROM 发送 CMD0 + CMD1,让 eMMC 进入 Boot Mode
  • eMMC 自动从 Boot Partition 输出数据,BootROM 接收并搬运到 SRAM
  • 执行完毕后,eMMC 切回正常模式,后续由 Bootloader 访问 User Partition

我建议你在设计 eMMC 启动时,一定要确认 Boot Partition 是否使能。有些厂商的 eMMC 默认 Boot Partition 是关闭的,需要第一次烧录时通过专用命令开启。否则板子回来怎么都起不来。

UART 与 USB:调试阶段的救命稻草

这两种介质不是用来跑正式固件的,而是用于 工厂烧录 和 开发调试。

UART 下载模式:

  • BootROM 初始化 UART,等待主机发送特定握手信号
  • 通常使用 XMODEM / YMODEM 协议传输固件
  • 速度慢(115200 bps 是常态),但胜在简单可靠
  • 适合小容量 Bootloader 的烧录

USB 下载模式:

  • BootROM 初始化 USB 设备控制器,枚举为 DFU(Device Firmware Update)设备
  • 主机通过 USB 批量传输数据,速度可达 MB/s 级别
  • 适合大容量固件的首次烧录

我的习惯:量产产品一定会保留 UART 下载模式作为 fallback。万一 eMMC 里的固件刷坏了,至少还能通过 UART 救回来。USB DFU 虽然快,但需要主机装驱动,产线环境不一定方便。

启动模式选择:硬件引脚 vs 寄存器

芯片怎么知道该从哪个介质启动?两种方式:

1. Boot Mode Pin(硬件引脚)

芯片复位时,采样特定 GPIO 的电平状态,组合成启动介质编号。

// 典型 Boot Mode 引脚映射(以某 ARM SoC 为例)
// BOOT[2:0] 引脚电平决定启动介质
// 000 - NOR Flash (SPI)
// 001 - NAND Flash
// 010 - eMMC
// 011 - SD Card
// 100 - UART Download
// 101 - USB DFU
// 110 - Reserved
// 111 - Reserved

硬件引脚的好处是——不需要任何软件干预,上电瞬间就决定。缺点是占用了 GPIO,而且一旦 PCB 打样完成,启动顺序就固定了。

2. Boot Mode 寄存器(软件配置)

有些芯片支持在 BootROM 执行初期,通过读取 OTP(One-Time Programmable)或 EFUSE 中的值来决定启动介质。这种方式更灵活,但需要提前烧录配置。

更常见的是 混合模式:硬件引脚决定第一优先级,如果该介质启动失败,BootROM 回退到寄存器配置的次选介质。

避坑指南:硬件引脚采样是在复位释放瞬间完成的。如果引脚上有较大的 RC 延迟(比如接了上拉电阻和电容),电平可能还没稳定,BootROM 就读到了错误的值。我建议 Boot Mode 引脚不要加滤波电容,上拉/下拉电阻用 4.7kΩ ~ 10kΩ 即可。

启动流程全景图

下面这张图展示了从芯片上电到 BootROM 完成介质选择、加载代码、跳转执行的完整流程:

BootROM 启动流程与介质选择 BootROM 启动流程与介质选择 芯片上电 / 复位 采样 Boot Mode Pin / 寄存器 根据模式选择启动介质 NOR Flash:XIP 直接执行 NAND/eMMC/SD:搬运到 SRAM UART/USB:等待主机下载 校验代码完整性 → 跳转执行 Bootloader 开始运行 💡 说明: NOR Flash 支持 XIP,无需搬运;NAND/eMMC/SD 需先搬运到内部 SRAM;UART/USB 为下载模式,用于调试和烧录。

实际项目中的启动策略

讲完理论,说说我在实际项目中怎么用这些知识。

案例:一款工业网关产品

  • 主芯片:某 ARM Cortex-A7 双核
  • 启动介质:SPI NOR (16MB) + eMMC (8GB)
  • 启动策略:
    1. Boot Mode Pin 设为 NOR Flash 启动
    2. NOR 中存放 Bootloader(U-Boot SPL)
    3. U-Boot SPL 初始化 DRAM,然后从 eMMC 加载完整的 U-Boot 和 Linux 内核
    4. 如果 eMMC 读取失败,回退到 NOR 中的救援系统(一个迷你的 busybox 环境)

这个方案的好处是:NOR 只放关键代码,容量需求小;eMMC 放系统和应用,容量大、成本低。而且万一 eMMC 坏了,还能通过 NOR 里的救援系统远程修复。

注意:多级启动时,每一级的代码大小都要严格控制。比如 SPL 通常限制在 64KB 以内,因为内部 SRAM 就那么大。我曾经见过一个团队把 SPL 写到了 80KB,结果链接时才发现放不下,只能砍功能重写。

小结

启动介质和模式选择,是 BootROM 设计的第一个关键决策。选对了,后续开发顺风顺水;选错了,可能整个项目都要推倒重来。

我的建议是:

  • 小容量固件(<16MB):优先考虑 SPI NOR,省心省力
  • 大容量固件(>128MB):eMMC 是主流,注意 Boot Partition 配置
  • 成本敏感:NAND 可以选,但一定要做好坏块管理和 ECC
  • 调试阶段:保留 UART 或 USB 下载模式作为 fallback
  • Boot Mode Pin:不要加滤波电容,电阻值选 4.7kΩ ~ 10kΩ