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 卡:

  1. 开发调试阶段:方便更新固件
  2. 数据记录:日志、配置备份等非关键数据
  3. 用户可更换的存储:比如相机、音乐播放器

对于 Bootloader 本身,我强烈不建议把启动代码放在 SD 卡上。除非你的 SoC 支持 SD 卡启动,并且你有可靠的防拔插机制。

3.5 不同介质对分区的影响

选定了存储介质,分区方案就跟着定了。这里我总结了几条核心原则:

分区设计原则:

  • NOR Flash:分区按扇区对齐,Bootloader 放在最前面,配置参数放在最后(减少擦写次数)
  • NAND Flash:必须预留坏块表空间,Bootloader 使用强块,分区大小考虑 ECC 开销
  • eMMC:利用硬件 Boot 分区,User Data 分区按 4KB 对齐(eMMC 的擦除块大小)
  • SD 卡:使用标准 MBR/GPT 分区表,Bootloader 放在第一个分区之前(如果 SoC 支持)

下面这张图展示了四种介质的分区布局差异:

四种存储介质分区布局对比 NOR Flash Bootloader (XIP) 应用程序 配置参数 NAND Flash 坏块表 (BBT) Bootloader (强块) 内核 + 文件系统 数据分区 (含ECC) eMMC Boot 分区 1 Boot 分区 2 (备份) RPMB (安全区) UDA (用户数据) SD 卡 MBR/GPT Bootloader (可选) FAT32 分区 ext4 分区 说明:NOR 分区最简单,NAND 需要坏块管理,eMMC 有硬件分区,SD 卡使用标准分区表

3.6 选型决策流程

在实际项目中,我一般按这个流程选型:

  1. 容量需求:小于 64MB → NOR Flash;大于 64MB → NAND/eMMC/SD
  2. 启动要求:需要 XIP → NOR Flash;不需要 → 其他
  3. 可靠性要求:工业级(-40~85℃)→ eMMC 或 NOR;消费级 → NAND/SD
  4. 成本敏感:大批量 → 裸 NAND + 软件 FTL;小批量 → eMMC 省开发时间
  5. 可维护性:需要现场升级 → eMMC(有 Boot 分区保护);不需要 → 任意

我的建议:如果你在做新产品,预算允许的话,优先选 eMMC。虽然单价比裸 NAND 贵 1~2 美元,但省掉的软件开发和调试时间,绝对值这个差价。我见过太多团队在 NAND 的坏块管理上翻车,最后项目延期三个月。