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(逻辑块地址),你不需要关心物理页和坏块管理。
启动流程大概是这样的:
- BootROM 初始化 SD/MMC 控制器,发送 CMD0 让卡进入 SPI 或 SD 模式
- 发送 CMD8 检查卡是否支持 1.8V/3.3V 信号
- 发送 ACMD41 获取卡的工作电压范围,等待卡就绪
- 发送 CMD2 获取 CID(卡标识符),CMD3 获取 RCA(相对地址)
- 发送 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 引脚通过电阻上拉或下拉,而不是直接接电源或地。这样万一需要改启动模式,飞线就能解决,不用重新打板。
下面这张图总结了四种启动模式的核心流程:
最后说一句,启动模式的选择不是孤立的。它和芯片选型、成本预算、启动速度要求、量产方案都强相关。我见过一个产品,为了省几毛钱选了 NAND Flash,结果量产时因为坏块问题返工了三次,最后算下来反而更贵。所以,做技术决策时一定要看全局。