3. 嵌入式存储介质:NOR Flash、NAND Flash、eMMC、SD卡的特点与选型
做Bootloader这些年,我接触过形形色色的存储介质。说实话,选错存储介质导致的翻车案例,我见过太多了。很多人觉得「不就是个存代码的芯片吗」,结果到了分区设计阶段才发现处处是坑。
这一章,咱们就把四种主流介质的脾气秉性摸清楚。你只有懂了它们的底层特性,才能做出靠谱的分区方案。
3.1 NOR Flash:简单可靠,但容量是硬伤
NOR Flash 是我个人最早接触的存储介质。它的接口是 SRAM 兼容的,CPU 可以直接在上面执行代码——这叫 XIP(eXecute In Place)。说白了,你不需要把代码拷贝到 RAM 里,直接跳转到 NOR Flash 的地址就能跑。
核心特点:
- 支持 XIP,代码原地执行
- 读速度快(~100ns 随机访问)
- 写/擦除速度慢(擦除一个扇区要几百毫秒)
- 容量通常 ≤ 128MB,成本高
- 坏块极少,几乎不需要坏块管理
我在一个工业控制项目里用过 NOR Flash 做 Bootloader 存储。当时选它的原因很简单:系统上电后需要立即响应,没时间等 RAM 初始化。NOR Flash 的 XIP 特性完美解决了这个问题。
避坑:我曾经遇到过一个案例,同事把 NOR Flash 的擦除次数当 NAND 来用。NOR 的擦除寿命只有 10 万次左右,虽然比 NAND 的 3000 次好很多,但如果你在 Bootloader 里频繁擦写配置参数,照样会提前报废。建议把频繁写操作放在 RAM 里,只在掉电前回写。
3.2 NAND Flash:大容量廉价,但管理复杂
NAND Flash 是嵌入式设备的主力存储。它的结构决定了它天生就有坏块——出厂时就带一些,使用过程中还会产生新的。这就带来了几个麻烦:
- 不能 XIP:必须把代码拷贝到 RAM 里执行
- 需要 ECC:每 512 字节数据需要 4~24 字节的纠错码
- 坏块管理:必须跳过坏块,或者用备用块替换
- 擦除寿命短:SLC 约 10 万次,MLC/TLC 只有 3000~5000 次
你想想看,如果你的 Bootloader 直接操作 NAND Flash 的原始扇区,一旦遇到坏块,启动就挂了。所以大部分方案都会在 NAND 上放一个 FTL(Flash Translation Layer),或者至少做一层坏块表。
我的经验:在 NAND 上部署 Bootloader 时,我建议把 Bootloader 放在最前面的几个块,并且用 MLC 的「强块」——也就是出厂标记为 good 的块。我曾经因为用了出厂坏块附近的块,结果设备在高温老化后启动失败,排查了三天才发现是坏块扩散导致的。
3.3 eMMC:省心之选,但内部黑盒
eMMC 本质上就是 NAND Flash 加上一个控制器,控制器里集成了 FTL、坏块管理、ECC、磨损均衡。对 Bootloader 开发者来说,eMMC 看起来就像一个普通的块设备——你可以按扇区读写,不用操心底层细节。
| 特性 | eMMC | 裸 NAND |
|---|---|---|
| 接口 | MMC 协议(8 线并行) | Raw NAND 接口 |
| 坏块管理 | 内部自动处理 | 需要软件管理 |
| ECC | 内部硬件完成 | 需要软件实现 |
| 分区 | 支持硬件分区(Boot、RPMB、UDA) | 纯软件分区 |
| 启动方式 | 支持 eMMC Boot 模式 | 需 SoC 支持 NAND Boot |
eMMC 的 Boot 分区是个好东西。很多 SoC 支持从 eMMC 的 Boot Area 直接启动,不需要 BootROM 去解析文件系统。我习惯把 Bootloader 放在 Boot 分区,把内核和文件系统放在 User Data 分区。这样即使文件系统坏了,Bootloader 还能通过 USB 或网络恢复。
注意:eMMC 的 Boot 分区默认是写保护的。你需要发特定的命令才能解锁写入。我曾经在量产脚本里忘了加解锁命令,结果 1000 台设备全部卡在 BootROM 阶段——嗯,那个周末我是在产线度过的。
3.4 SD 卡:通用但不可靠
SD 卡和 eMMC 的底层技术几乎一样——都是 NAND + 控制器。但 SD 卡有个致命问题:它是个可插拔设备。用户可能在任意时刻拔卡,这会导致:
- 文件系统损坏(突然掉电)
- 正在写入的扇区数据不完整
- 控制器缓存里的数据丢失
我建议只在以下场景使用 SD 卡:
- 开发调试阶段:方便更新固件
- 数据记录:日志、配置备份等非关键数据
- 用户可更换的存储:比如相机、音乐播放器
对于 Bootloader 本身,我强烈不建议把启动代码放在 SD 卡上。除非你的 SoC 支持 SD 卡启动,并且你有可靠的防拔插机制。
3.5 不同介质对分区的影响
选定了存储介质,分区方案就跟着定了。这里我总结了几条核心原则:
分区设计原则:
- NOR Flash:分区按扇区对齐,Bootloader 放在最前面,配置参数放在最后(减少擦写次数)
- NAND Flash:必须预留坏块表空间,Bootloader 使用强块,分区大小考虑 ECC 开销
- eMMC:利用硬件 Boot 分区,User Data 分区按 4KB 对齐(eMMC 的擦除块大小)
- SD 卡:使用标准 MBR/GPT 分区表,Bootloader 放在第一个分区之前(如果 SoC 支持)
下面这张图展示了四种介质的分区布局差异:
3.6 选型决策流程
在实际项目中,我一般按这个流程选型:
- 容量需求:小于 64MB → NOR Flash;大于 64MB → NAND/eMMC/SD
- 启动要求:需要 XIP → NOR Flash;不需要 → 其他
- 可靠性要求:工业级(-40~85℃)→ eMMC 或 NOR;消费级 → NAND/SD
- 成本敏感:大批量 → 裸 NAND + 软件 FTL;小批量 → eMMC 省开发时间
- 可维护性:需要现场升级 → eMMC(有 Boot 分区保护);不需要 → 任意
我的建议:如果你在做新产品,预算允许的话,优先选 eMMC。虽然单价比裸 NAND 贵 1~2 美元,但省掉的软件开发和调试时间,绝对值这个差价。我见过太多团队在 NAND 的坏块管理上翻车,最后项目延期三个月。