3、启动模式与介质:NOR Flash启动、NAND Flash启动、SD卡/eMMC启动、UART/USB下载模式

嵌入式系统上电后,CPU 第一件事就是去取指令。但指令从哪来?这就引出了启动介质的选择。说白了,不同的存储介质有完全不同的物理特性,Bootloader 必须「看菜下饭」。我早年做第一个项目时,就因为搞混了 NOR 和 NAND 的启动流程,板子死活跑不起来,折腾了两天才发现是映射地址搞错了。

今天我们就来拆解四种最常见的启动模式。每种模式都有它的脾气,理解了它们,你就能明白为什么有些芯片要配那么多启动引脚。

3.1 NOR Flash 启动:XIP 的优雅与局限

NOR Flash 最大的特点是支持 XIP(eXecute In Place,原地执行)。什么意思?CPU 可以直接在 Flash 上读指令、跑代码,不需要先把代码拷贝到 RAM 里。

核心特性:NOR Flash 的读时序和 SRAM 很像,地址线、数据线分开,CPU 可以直接映射访问。

我在项目中遇到过一块板子,NOR Flash 挂在 CS0 片选上,起始地址就是 0x00000000。CPU 复位后 PC 指针直接指向这个地址,开始执行第一条指令。整个过程一气呵成,没有任何搬运动作。

但 NOR 也有硬伤:

  • 写入慢:擦除和编程操作非常耗时,不适合频繁写操作
  • 容量小:同样成本下,NOR 的容量远小于 NAND
  • 价格贵:每 MB 成本大约是 NAND 的 5-10 倍

所以 NOR Flash 通常只用来放 Bootloader 的前几级代码,或者对实时性要求极高的场合。比如一些 DSP 芯片,上电后必须在微秒级内响应,这时候 XIP 就是刚需。

个人习惯:如果项目对启动速度有硬性要求,我会优先考虑 NOR Flash。虽然贵,但省去了代码搬运的时间,整体性价比反而更高。

3.2 NAND Flash 启动:大容量但需要「影子搬运」

NAND Flash 就不一样了。它没有独立的地址线,数据是通过 I/O 接口串行读写的。CPU 没法直接在 NAND 上执行代码——你想想看,读一条指令要发一堆命令、地址、等待时序,CPU 早饿死了。

所以 NAND 启动的套路是:先搬运,再执行。

芯片内部通常会有一个 ROM Code(也叫 BootROM),上电后它先运行,负责从 NAND Flash 里把 Bootloader 读到 SRAM 或 DDR 里,然后跳转过去执行。

我曾经踩过的坑:NAND Flash 出厂时可能有坏块!如果 Bootloader 恰好被放在坏块上,板子就变砖了。后来我学乖了,要么用硬件 ECC 校验,要么在烧录时把 Bootloader 放在固定好块区域。

NAND 启动的关键参数:

参数 说明 典型值
页大小 每次读写的最小单位 2KB / 4KB / 8KB
块大小 擦除的最小单位 128KB / 256KB / 512KB
ECC 强度 每页能纠正的比特数 4bit / 8bit / 24bit
启动加载大小 BootROM 一次性读取的字节数 4KB / 8KB / 16KB

这里要注意,BootROM 通常只读前几页。如果你的 Bootloader 超过这个大小,就需要分两阶段加载:第一阶段(SPL)先被读进来,然后 SPL 初始化 DDR,再把完整的 U-Boot 从 NAND 搬到 DDR 里。

3.3 SD 卡 / eMMC 启动:存储卡协议与启动分区

SD 卡和 eMMC 本质上是一类东西——都是基于 MMC 协议的块设备。它们内部有控制器,对外暴露的是 LBA(逻辑块地址),你不需要关心物理页和坏块管理。

启动流程大概是这样的:

  1. BootROM 初始化 SD/MMC 控制器,发送 CMD0 让卡进入 SPI 或 SD 模式
  2. 发送 CMD8 检查卡是否支持 1.8V/3.3V 信号
  3. 发送 ACMD41 获取卡的工作电压范围,等待卡就绪
  4. 发送 CMD2 获取 CID(卡标识符),CMD3 获取 RCA(相对地址)
  5. 发送 CMD7 选中卡,然后 CMD17 读取指定扇区的数据

嗯,这里要注意,eMMC 有一个特殊的 Boot Partition 概念。eMMC 内部可以划分出两个专用的启动分区(Boot Area Partition 1 和 2),容量通常为 4MB 或 8MB。芯片可以配置从哪个启动分区加载代码。

关键区别:SD 卡没有启动分区,Bootloader 通常放在固定偏移位置(比如第 0 扇区)。eMMC 有专门的启动分区,且支持「Boot Acknowledgement」模式,卡会主动告诉主机自己准备好了。

我在做一款消费类产品时,遇到过 eMMC 启动失败的问题。排查了半天,发现是 eMMC 的 RST_n 信号被拉低了,导致卡一直处于复位状态。后来在原理图上加了 RC 延时电路,问题就解决了。这种硬件时序问题,软件层面很难定位。

3.4 UART / USB 下载模式:调试与量产的法宝

最后说说下载模式。这种模式不是从存储介质启动,而是通过通信接口把代码灌进芯片里。

UART 下载模式:

  • 芯片内部 BootROM 初始化 UART,等待接收数据
  • 上位机通过 XMODEM / YMODEM 协议发送二进制文件
  • BootROM 把收到的数据写入 SRAM 或 DDR,然后跳转执行

我习惯在开发阶段保留 UART 下载功能。万一 Flash 里的 Bootloader 刷坏了,还能通过串口救回来。说白了,这就是嵌入式系统的「安全模式」。

USB 下载模式:

  • 芯片模拟成一个 USB 设备(通常是 HID 或 DFU 类)
  • 上位机通过 USB 批量传输数据,速度比 UART 快得多
  • 典型场景:手机刷机、路由器刷固件

避坑指南:我曾经在量产时发现,有些 USB 线质量太差,导致下载过程中断。后来我们规定产线必须用带屏蔽的 USB 线,并且下载完成后要做 CRC 校验。别小看这些细节,产线上一分钟卡住,损失就是几千块。

3.5 启动模式选择与硬件设计

芯片厂商通常会提供多个 BOOT 引脚,通过高低电平组合来选择启动模式。比如:

BOOT[1:0] 启动介质 典型应用
00 NOR Flash 高速启动、实时控制
01 NAND Flash 大容量存储、成本敏感
10 SD / eMMC 消费电子、通用计算
11 UART / USB 调试、量产烧录

设计硬件时,我建议把 BOOT 引脚通过电阻上拉或下拉,而不是直接接电源或地。这样万一需要改启动模式,飞线就能解决,不用重新打板。

下面这张图总结了四种启动模式的核心流程:

四种启动模式核心流程对比 NOR Flash 启动 CPU 直接 XIP 执行 无需搬运代码 启动速度:微秒级 NAND Flash 启动 BootROM 搬运到 SRAM 需处理坏块和 ECC 启动速度:毫秒级 SD / eMMC 启动 MMC 协议初始化 支持启动分区 启动速度:毫秒级 UART / USB 下载 协议接收二进制 写入 RAM 后执行 启动速度:依赖接口 CPU 复位 → 读取 BOOT 引脚状态 选择对应启动介质 XIP 执行 Bootloader 搬运 + ECC 校验 MMC 协议读取 协议接收并执行 💡 说明: 实际芯片可能支持多种启动模式组合,通过 BOOT 引脚或 OTP 配置。部分芯片支持「回退机制」——首选启动失败后自动切换到备用模式。

最后说一句,启动模式的选择不是孤立的。它和芯片选型、成本预算、启动速度要求、量产方案都强相关。我见过一个产品,为了省几毛钱选了 NAND Flash,结果量产时因为坏块问题返工了三次,最后算下来反而更贵。所以,做技术决策时一定要看全局。