SD NAND 内置控制器架构
编制日期 2026-10-14 | 版本号 Rev 1.0
存储技术探讨系列 · 面向 FAE 与硬件设计人员 · 主色深青 #0D5C6B
SD NAND 是 XTX(芯天下)存储产品线里「把 NAND 做成即插即用贴片器件」的主力形态。现场交流中反复出现的疑问高度集中:它内部到底装了什么?主控还要不要写 FTL?两个电源怎么接?能不能用 GPIO 直接切掉 VCC 做低功耗?为什么标称速度跑不满?为什么一断电文件系统就坏?
本文把这些问题拆成 12 章,从定义与谱系讲到内部结构、协议层、性能、电源门控、可靠性与硬件设计,最后给出故障速查与选型核查清单。所有数值只给量级并注明「典型值」,具体参数一律以对应型号的规格书为准。
结论:SD NAND 本质上是「把一整套 SSD 控制器子系统、NAND 裸片和 SD 接口协议栈封进一枚贴片器件」,主控侧因此从「管理 NAND」退化为「管理 SD 总线 + 管理电源 + 管理文件系统一致性」三件事;所有现场故障,八成以上都出在这三件事的边界上,而不是出在 NAND 颗粒本身。
适用对象:XTX 存储芯片 FAE、硬件工程师、嵌入式驱动工程师、方案选型人员。文中「典型值」均为工程量级参考,不构成任何型号的参数承诺。
1 · SD NAND 是什么
先把定义钉死:SD NAND 不是「一张贴片的 TF 卡」,而是把 NAND 裸片、控制器裸片和 SD 接口协议栈一起封装成的一枚 LGA 或 BGA 贴片器件。它对外的全部语义就是 SD 总线,对内的全部复杂度都被控制器吃掉了。
1.1 定义:裸 NAND + 控制器 + SD 接口
一句话概括:SD NAND = NAND 裸片 + 内置控制器(固件 + ECC + FTL)+ SD 物理层与协议栈,三者封装在同一枚贴片器件内。主控侧只要具备 SDIO 主机控制器(或普通 SPI 主机),就能像访问一张 SD 卡那样访问它,而不需要实现任何 NAND 相关的管理逻辑。
这个定义包含三层含义,缺一不可:
- 裸 NAND 层:内部仍是原始的 NAND 阵列,有坏块、有擦写次数上限、有读干扰与数据保持问题,物理规律不会因为封装形态而改变;
- 控制器层:内置控制器接管了 ECC 校验与纠错、坏块替换、磨损均衡、垃圾回收、逻辑地址到物理地址映射、掉电保护这六类工作;
- SD 接口层:对外只暴露 CLK、CMD、DAT0~DAT3(可降宽使用)等 SD 总线信号,命令集与响应格式遵循 SD 规范,因此可以直接复用主控芯片上成熟的 SDIO 驱动。
需要特别强调的是:SD NAND 与 TF 卡(microSD)在协议层是同源的,这正是它能被现有 SDIO 驱动直接识别的根本原因;但二者在颗粒筛选等级、工作温度范围、供货形态与焊接可靠性要求上完全不是一回事,不能简单地当作「把卡焊死在板子上」来处理。
| 维度 | SD NAND | TF 卡 / microSD | 对设计的实际影响 |
|---|---|---|---|
| 物理形态 | LGA 或 BGA 贴片芯片 | 可插拔卡 + 卡座 | SD NAND 焊后不可更换,返修成本高 |
| 接口协议 | SD 物理层 + SD 命令集 | SD 物理层 + SD 命令集 | 驱动可复用,初始化流程基本一致 |
| 控制器位置 | 封装内部,与颗粒同厂匹配 | 卡内部,由卡厂自行匹配 | SD NAND 的固件与颗粒由原厂统一验证 |
| 颗粒等级 | 按芯片级规格书管控 | 按消费类介质管控 | 工业与宽温场景需核对规格书温度段 |
| 容量与供货 | 固定型号、固定容量档 | 同型号可能换颗粒 | SD NAND 供货一致性更好,利于量产 |
| 空间占用 | 器件本体,无卡座 | 卡座体积往往大于卡本身 | SD NAND 在薄型与小面积设备里优势明显 |
表 1-1 · SD NAND 与 TF 卡的对照(定性对照,不涉及具体型号参数)
从命名与供货的角度看,SD NAND 这类器件的型号通常直接体现容量档位与封装形式,而不直接体现内部颗粒的具体代际。这对量产客户其实是一件好事:同一个型号在不同批次之间应当保持一致的对外行为与容量,内部颗粒方案若有调整,也应当在规格书或变更通知中体现,而不是像消费类介质那样悄悄更换方案。
容量档位方面,SD NAND 常见覆盖从几百兆字节到数十吉字节的区间,具体档位取决于产品规划。选型时不要只按当前够用来定容量,而要把预留空间一并考虑进去:容量占用率越高,内部回收越频繁,稳态写入速度与寿命表现都会受影响。经验上,为业务数据之外的空闲空间留出一定比例,往往比单纯追求更大的标称容量更有效。
1.2 典型封装形态:LGA 与 BGA 贴片
SD NAND 常见的贴片封装有两种形态,选型时主要在厚度、引脚密度、可制造性三者之间权衡。
LGA(Land Grid Array)把焊盘平铺在器件底面,厚度可以做得较薄,引脚数量通常较少,常见只有电源、地、CLK、CMD 与若干数据线等不到十个有效信号。它的优点是占位小、厚度低,返修时可以用热风或烙铁处理,缺点是可引出的信号有限,难以把多个 NAND 通道或额外测试脚拉到外部。
BGA(Ball Grid Array)用底面锡球阵列代替平面焊盘,同样的占位可以布置更多引脚,有利于把更多通道、更多电源脚和测试脚引出。代价是焊点在器件底部不可见,焊接质量必须依赖 X 光抽检;同时 BGA 对焊盘设计、钢网开口与回流曲线的要求更高。
| 对比项 | LGA 贴片 | BGA 贴片 | 选型提示 |
|---|---|---|---|
| 焊点形式 | 底面平面焊盘 | 底面锡球阵列 | 焊盘设计必须严格按推荐封装 |
| 可引出引脚 | 较少,通常十个以内 | 较多,可达二十球以上 | 需要额外测试脚时优先 BGA |
| 器件厚度 | 较薄,适合超薄设备 | 略厚 | 厚度敏感项目优先 LGA |
| 焊接检查 | 部分焊盘可见 | 焊点不可见,需 X 光 | 量产需规划 X 光抽检比例 |
| 返修难度 | 相对容易 | 需要专业返修台 | 试产阶段评估返修方案 |
| 典型应用 | 穿戴、小型模组、薄型终端 | 功能较多的主控模组 | 按引脚需求与厚度要求选 |
表 1-2 · LGA 与 BGA 两种封装形态的工程权衡
无论选哪种封装,都建议在试产阶段做一次焊接可靠性验证:包括回流后的外观检查、必要的 X 光抽检,以及温度循环后的功能复测。贴片器件焊上之后无法像可插拔介质那样单独更换,焊接不良的代价是整板返修,把这道验证放在试产阶段完成,成本远低于量产后再补救。
1.3 与 TF 卡 / SD 卡的关系与区别
这个说法只对了一半。对的一半是:二者在 SD 物理层与命令集上确实同源,所以主控驱动几乎不用改。错的一半是:把二者当成同一类物料来管理,会在量产阶段付出代价。
TF 卡是可插拔的消费类介质,它的颗粒筛选标准、工作温度范围、供货周期都按消费类介质定义,而且同型号在不同批次可能更换内部颗粒与控制器方案。SD NAND 是板载焊接的芯片级器件,颗粒与固件由原厂统一匹配与验证,供货形态固定,寿命与温度指标写在芯片规格书里,并且焊上去之后不可更换。
工程后果很直接:用消费类 TF 卡的思维去做工业产品的备料与寿命评估,会低估供货一致性风险,也会高估现场可维护性。反过来,用芯片级思维去要求 TF 卡,又会因为卡座接触、卡体变形等机械问题而误判为器件失效。
把关系讲清楚之后,实际工作中的判断就简单了:凡是主控侧的代码、驱动与协议交互,可以按 SD 卡来理解和调试;凡是物料、寿命、温度与供货一致性的判断,必须按芯片规格书来。
| 常见说法 | 判断 | 正确理解 |
|---|---|---|
| SD NAND 就是贴片的 TF 卡 | 错 | 协议同源,但颗粒等级、供货形态与寿命定义不同 |
| 既然是 SD 接口,主控就不用管存储了 | 错 | 主控仍要管总线、电源门控与文件系统一致性 |
| SD NAND 没有坏块 | 错 | 内部仍有坏块,只是由控制器替换掉,对主机不可见 |
| SD NAND 可以随意断电 | 错 | 写入过程中断电是数据损坏的主要来源 |
| SD NAND 速度就是 SD 接口速率 | 错 | 接口速率是上限,稳态速度受 SLC Cache 与回收限制 |
| SD NAND 焊上去就一定能识别 | 错 | 上电时序、电平与走线不达标时识别会失败 |
表 1-3 · 关于 SD NAND 的高频误解与正确理解
把上面三条误解纠正之后,还有一个更实际的问题:拿到一颗器件,怎么快速判断它是不是 SD NAND?下表给出四个判据,按顺序核对基本就能确定形态,避免把 SPI NAND、裸 NAND 或普通存储卡混为一谈。
| 判据 | SD NAND 的表现 | 容易误判的情况 | 确认方式 |
|---|---|---|---|
| 外形 | 贴片芯片,板上没有卡座 | 被当成普通存储卡 | 看封装是 LGA 还是 BGA |
| 接口 | 具备时钟、命令与数据线 | 被当成 SPI 存储器件 | 看是否存在命令线与多根数据线 |
| 驱动 | 走 SDIO 或 SPI 驱动栈 | 被当成裸 NAND 处理 | 看初始化是否需要命令序列 |
| 管理 | 存储管理在器件内部 | 以为主控仍要自行实现 | 看是否有协议层命令交互 |
表 1-4 · 现场快速识别 SD NAND 的四个判据
2 · 在存储谱系里的位置
把 SD NAND 放进 raw NAND → SPI NAND → SD NAND → eMMC → UFS 这条谱系里看,它的定位就非常清楚:用最低的主控侧代价,换到「不用自己写 FTL」和「贴片小封装」这两件事。
2.1 从 raw NAND 到 UFS 的梯度
这条谱系的本质,是「存储管理复杂度从主控侧搬到器件内部」的过程。越靠左,主控要自己做的事越多,器件的接口越原始;越靠右,器件内部越像一个完整的固态存储系统,主控越像一个单纯的「总线主机」。
在这条谱系上,SD NAND 的位置很特殊:它向左承接了 SPI NAND 的低成本与小封装,向右借用了 eMMC 那种「内部自带控制器」的思路,但接口选择了生态最成熟、IP 最普及、引脚最少的 SD 总线。因此它特别适合主控资源有限、Flash 经验不多、但又希望摆脱裸 NAND 管理负担的项目。
| 形态 | 对外接口 | 控制器位置 | 主控需实现的工作 | 主控侧代价 |
|---|---|---|---|---|
| raw NAND | 并行 ONFI 或 Toggle | 无,在主控侧 | FTL、ECC、坏块、磨损均衡、回收全部自研 | 最高 |
| SPI NAND | SPI 串行 | 无,在主控侧 | FTL、ECC、坏块管理,接口驱动简单 | 高 |
| SD NAND | SDIO 或 SPI | 器件内部 | SD 总线驱动 + 文件系统 + 电源管理 | 低 |
| eMMC | eMMC 总线 | 器件内部 | eMMC 主机驱动 + 文件系统 | 中低 |
| UFS | UFS 与 M-PHY | 器件内部 | UFS 主机驱动 + 文件系统 | 中 |
表 2-1 · 五档存储形态的主控侧代价对照(定性)
需要补充一点:这条谱系并不是越靠右越好的单向选择。越靠右的形态往往意味着更高的器件成本、更复杂的主机 IP 要求,以及更严格的电源与布线约束。对很多项目来说,SD NAND 恰好落在「够用且代价最小」的位置上:它用最普及的 SD 总线换来了零 FTL 负担,同时避开了更高阶形态在 IP、封装与成本上的门槛。
2.2 主控侧负担与集成度的反向关系
把「主控侧负担」拆成具体的任务项,就能更直观地看到 SD NAND 帮主控省掉了什么。下表把每项工作在不同形态下的归属列出来,标注为主控的工作就是需要自己写代码、自己踩坑的部分。
| 工作项 | raw NAND | SPI NAND | SD NAND | eMMC / UFS |
|---|---|---|---|---|
| 接口驱动 | 主控 | 主控 | 主控 | 主控 |
| ECC 校验与纠错 | 主控 | 主控 | 器件内部 | 器件内部 |
| 坏块扫描与替换 | 主控 | 主控 | 器件内部 | 器件内部 |
| 磨损均衡 | 主控 | 主控 | 器件内部 | 器件内部 |
| 垃圾回收 | 主控 | 主控 | 器件内部 | 器件内部 |
| 逻辑到物理地址映射 | 主控 | 主控 | 器件内部 | 器件内部 |
| 掉电保护策略 | 主控 | 主控 | 器件内部部分 + 主控 | 器件内部部分 + 主控 |
| 文件系统 | 主控 | 主控 | 主控 | 主控 |
| 电源与时序设计 | 主控侧硬件 | 主控侧硬件 | 主控侧硬件 | 主控侧硬件 |
把这张表读透,可以得到一个对排期很有用的结论:换用 SD NAND 之后,主控侧软件工作量的下降幅度,远大于硬件工作量的下降幅度。电源、时序、走线、去耦这些硬件责任一项都没有减少;而 FTL、ECC、坏块管理、磨损均衡这些软件复杂度几乎全部消失。因此项目排期时,应当把原本用于存储管理软件的资源,转移到硬件验证与系统级断电策略上——这才是换用 SD NAND 之后真正的投入重点。
表 2-2 · 主控侧任务归属对照。注意最后两行:文件系统与电源时序在任何形态下都留在主控侧
表里倒数第二行与倒数第一行是现场最容易漏掉的部分。换用 SD NAND 并不会自动解决文件系统一致性问题,也不会自动解决电源时序问题。
器件内部只能保证「它自己收到的那一笔写操作」尽量完整,无法保证上层的目录结构、分配表与日志在断电瞬间处于一致状态。文件系统一致性与电源门控策略,始终留在主控侧,这也就是本文第 9 章要重点展开的原因。
2.3 选型落点:什么时候选 SD NAND
选型时建议按下面这张表逐条对照。如果前四行的答案都是「是」,SD NAND 通常就是这条谱系上性价比最高的落点。
| 判断条件 | 选 SD NAND | 建议改选其他形态 |
|---|---|---|
| 主控是否已有成熟的 SDIO 主机 IP | 是 | 没有 SDIO 但有 SPI 时,可退到 SPI 模式 |
| 团队是否有精力自研或移植 FTL | 否,希望零 FTL | 有能力做 FTL 且成本敏感,可考虑 SPI NAND |
| PCB 面积与厚度是否受限 | 是,需要小封装贴片 | 空间充裕且要插拔,可用 TF 卡 + 卡座 |
| 是否需要连续带宽高于 SD 接口上限 | 否 | 需要更高带宽时评估 eMMC 或 UFS |
| 是否需要可现场更换介质 | 否,焊死即可 | 需要现场更换时用 TF 卡 |
| 容量档位是否在 SD NAND 覆盖范围内 | 是 | 超大容量需求评估 eMMC |
表 2-3 · SD NAND 的选型落点判断表
把判断条件落到具体的产品类型上,可以更直观地看到各形态的适用边界。下表按常见产品类型给出推荐,供方案阶段快速参考;最终仍然要以容量、带宽、温度与供货四项硬指标为准。
| 产品类型 | 典型需求 | 推荐形态 | 推荐理由 |
|---|---|---|---|
| 穿戴与小型模组 | 体积小、厚度薄、功耗敏感 | SD NAND 贴片 | 省掉卡座,厚度与面积可控 |
| 工业控制与网关 | 供货一致、宽温、长期可用 | SD NAND 或 eMMC | 按容量与稳态带宽决定 |
| 消费类可换介质 | 用户可自行更换与扩容 | 存储卡加卡座 | 必须保留可插拔能力 |
| 数据记录与日志 | 持续写入量大、不能丢数据 | 按稳态带宽评估后决定 | 必要时升级到更高带宽形态 |
| 低成本小数据量 | 只存配置、固件与少量日志 | SPI NAND 或 SD NAND | 看主控资源与综合成本 |
表 2-4 · 按产品类型的形态推荐(供方案阶段参考)
最后给一条迁移建议:从 SPI NAND 迁移到 SD NAND 时,工作量主要在主机驱动,而不在硬件。接口从 SPI 换成 SDIO(或继续用 SPI 模式兼容),硬件上主要是增加数据线与核对电源;而软件上则可以删除整套 FTL 与坏块管理代码,同时引入 SD 总线驱动栈。反过来从 SD NAND 往更高带宽形态迁移时,硬件与 IP 的改动量会明显变大,需要重新评估主控能力。
3 · 内部架构拆解
本章是全文的锚点。第 3 章的框图理清楚之后,后面关于供电、协议、性能、可靠性与硬件设计的所有讨论,都能在这张图上找到对应位置。
3.1 六大功能模块
虽然不同厂商的模块划分与命名略有差异,但从功能角度看,SD NAND 内部基本都可以拆成六个模块:SD 接口 PHY、SD 协议栈、FTL 映射层、ECC 引擎、NAND 通道控制器,以及内部的 SRAM 与 ROM。前四个构成主数据通路,NAND 通道负责把 FTL 的结果真正落到颗粒上,SRAM 与 ROM 则是支撑这套逻辑运行的存储资源。
对照框图,有几点值得单独说明:
- SD 接口 PHY 负责电气层:采样时钟、驱动数据线、处理 1.8V 与 3.3V 的 IO 电平切换。上电时它必须先于协议栈稳定工作,因此第 5 章讲的电源时序本质上是在约束这一层。
- SD 协议栈 负责命令解析、CRC 校验、响应回送与卡状态机迁移。主机看到的所有「卡状态」,都是这一层维护出来的。
- FTL 映射层 负责把主机给出的逻辑块地址翻译成物理页地址,同时维护无效页回收与磨损计数的元数据。
- ECC 引擎 在写入时生成校验码,在读取时做解码与纠错。它的纠错能力直接决定颗粒在数据保持退化后还能不能被正确读出。
- NAND 通道控制器 负责产生符合颗粒时序要求的命令序列与时序信号,是「FTL 的决定」和「颗粒的动作」之间的翻译层。
- 内部 SRAM 与 ROM 分别承担运行时的数据缓冲与映射表缓存、以及固件代码与启动代码的存放。
| 模块 | 主要职责 | 出问题时的典型表现 |
|---|---|---|
| SD 接口 PHY | 电气层收发、时钟采样、IO 电平切换 | 识别失败、高速模式掉卡、误码率高 |
| SD 协议栈 | 命令解析、CRC 校验、状态机维护 | 命令超时、响应错误、状态机卡死 |
| FTL 映射层 | 逻辑地址到物理地址映射、元数据维护 | 写入变慢、容量异常、地址越界报错 |
| ECC 引擎 | 编码校验码、解码并纠错 | 读失败、不可纠正错误上报、数据位翻转 |
| NAND 通道控制器 | 产生颗粒命令序列与时序 | 编程或擦除失败、通道超时 |
| 内部 SRAM 与 ROM | 数据缓冲、映射表缓存、固件存放 | 启动异常、掉电后映射表不一致 |
表 3-1 · 六大模块职责与故障表现对照
六个模块之间存在明确的先后与依赖关系:接口 PHY 先于协议栈工作,协议栈解析出的命令交给 FTL 处理,FTL 决定写到哪个物理页,ECC 引擎负责给这份数据加上保护,最后由 NAND 通道把一切落到颗粒上。任何一环出问题,表现出来的现象往往是「上一层在报错」,这正是排查时必须按图索骥、逐层下钻的原因。
3.2 数据流:从主机命令到 NAND 颗粒
以一次多块写命令为例,数据要穿过四层功能模块才能真正落到颗粒上。整个过程对主机是透明的:主机只看到命令发出去、响应收回来,中间的地址映射与纠错完全不可见。
这条链路上有几个工程上必须记住的点:
- 写放大发生在 FTL 层:主机写一个逻辑页,内部可能触发读旧块、写新页、标记旧页无效,最终产生多次物理写;
- 编程耗时是主要瓶颈:命令解析与地址转换都在微秒量级,而 NAND 编程在百微秒到毫秒量级,因此稳态写入速度往往由颗粒编程时间决定,而不是由 SD 接口速率决定;
- 响应返回不等于数据已落定:部分器件在内部仍有缓存与回写过程,响应只代表器件已经接收并承诺处理,这一点在第 9 章的断电风险窗口里会再次出现。
| 阶段 | 所在模块 | 耗时量级(典型) | 说明 |
|---|---|---|---|
| 命令下发与传输 | 主机 + 接口 PHY | 微秒到百微秒 | 取决于总线宽度与时钟频率 |
| 命令解析与 CRC 校验 | SD 协议栈 | 微秒量级 | 相对总线传输可忽略 |
| 逻辑地址转换 | FTL 映射层 | 微秒量级 | 命中缓存时更快,未命中需读表 |
| ECC 编码 | ECC 引擎 | 微秒量级 | 随码长与纠错能力增加 |
| NAND 编程 | NAND 通道 + 颗粒 | 百微秒到毫秒量级 | 整条链路的主要耗时来源 |
| 响应回送 | SD 协议栈 | 微秒量级 | 主机可继续发起下一笔 |
表 3-2 · 一次写操作的阶段分解与耗时量级(均为典型值,非具体器件指标)
读路径与写路径的结构相似,但瓶颈位置不同。读操作不需要编程等待,因此耗时主要由颗粒读取时间、ECC 解码时间与总线传输时间三部分构成。当数据保持退化导致错误位增多时,ECC 解码会变慢,甚至触发重读与内部数据刷新,这时读延迟会出现明显毛刺——这是判断器件是否进入保持退化阶段的重要线索,也是第 10 章要讨论的可靠性监控项之一。
3.3 内部 RAM / ROM 与固件
内部 SRAM 与 ROM 的容量通常不大,但它们的存在决定了控制器能不能正常工作。SRAM 主要用于三类用途:数据缓冲、映射表缓存、以及固件运行时的栈与变量区;ROM 则存放启动代码与部分固件,器件上电后首先执行它完成自检与初始化。
| 资源 | 主要用途 | 工程含义 |
|---|---|---|
| 内部 SRAM · 数据缓冲 | 暂存主机下发的数据块 | 决定了单笔传输能否连续不中断 |
| 内部 SRAM · 映射表缓存 | 缓存热点映射表项 | 缓存未命中会额外读表,增加延迟 |
| 内部 SRAM · 运行区 | 固件栈与变量 | 容量紧张时固件策略会趋于保守 |
| 内部 ROM · 启动代码 | 上电自检与初始化 | 上电时序不达标时,这一步就可能失败 |
| 内部 ROM · 固件主体 | FTL 与协议处理逻辑 | 固件版本决定行为细节,跨版本需重新验证 |
表 3-3 · 内部 RAM 与 ROM 的用途与工程含义
最后要明确「边界在哪里」。SD NAND 把复杂度封进器件内部,但边界本身并没有消失,只是从代码层面转移到了硬件、时序与系统策略层面。下表把四条最关键边界列出来,它们也是后续章节反复回到的位置。
| 边界位置 | 边界以上的内容 | 边界以下的内容 | 工程含义 |
|---|---|---|---|
| SD 总线 | 主控的驱动、块设备与文件系统 | 器件内部全部实现 | 调试时只需要抓总线交互 |
| 电源与时序 | 主控侧的电源与时序设计 | 器件提出的电源与时序要求 | 硬件责任始终在板级 |
| 掉电时机 | 主控决定何时可以断电 | 器件尽力保护已接收的数据 | 责任无法完全转移给器件 |
| 性能预期 | 主控侧的带宽预算与调度 | 器件的稳态读写能力 | 必须按稳态值做预算 |
表 3-4 · 内部模块与主控侧的四条关键边界
把边界讲清楚还有一个非常实际的作用:它决定了问题该找谁。总线交互异常找驱动与协议实现,电源与时序异常找硬件设计,断电后数据损坏找系统软件与断电策略,性能达不到预期则先核对是不是预期本身定错了。边界清晰,能省下大量跨部门沟通成本,也能避免「先把器件换掉试试」这种低效的排查路径。
后面所有章节都可以映射到第 3 章的框图:第 5 章讲 PHY 的电源,第 6 章讲协议栈的命令,第 8 章讲 FTL 与 NAND 通道共同决定的速度,第 9 章讲 SRAM 中缓存数据何时才算真正落定,第 10 章讲 ECC 与坏块余量,第 11 章讲 PHY 之外的硬件设计。
4 · 控制器替主控做的六件事
这是 SD NAND 最大的价值所在:把 NAND 管理里最难、最容易出错的六件事全部搬进器件内部。理解这六件事的边界,比理解它们的实现细节更重要——因为现场问题几乎都出在边界上。
4.1 ECC 与坏块管理
ECC(错误校验与纠正)是 NAND 能可靠工作的前提。NAND 天生会有位翻转:随着擦写次数增加、随着数据保持时间拉长,读出的比特里出现错误的概率会上升。控制器在写入时为每个扇区生成校验码,读取时用校验码定位并纠正错误位。
需要明确的是:ECC 的纠错能力有上限。当某个页面的错误位数超过纠错能力,控制器就会上报不可纠正错误,这一页数据就此丢失。因此「ECC 能纠错」不等于「数据永远不会坏」,它只是把错误率压到工程可接受的范围内。
| ECC 相关概念 | 含义 | 工程提示 |
|---|---|---|
| 纠错能力 | 单个码字内能纠正的错误比特数量级 | 越高越占冗余空间,也越增加编码延迟 |
| 码字长度 | 一次编码覆盖的数据块大小 | 常见按扇区或按页组织 |
| 不可纠正错误 | 错误位数超出纠错能力 | 表现为读失败,需在系统层有兜底 |
| 数据保持退化 | 长期不通电导致的电荷流失 | 高温存放会加速退化 |
| 读干扰 | 反复读同一块影响相邻页 | 控制器通过重读与刷新缓解 |
| 重读与数据刷新 | 错误接近阈值时重写数据 | 由固件策略决定,主机不可见 |
表 4-1 · ECC 相关概念与工程提示(不涉及具体纠错位数参数)
从系统的角度看,ECC 的意义在于把「一定会发生的位错误」变成「概率极低的不可纠正错误」。因此评估 ECC 是否够用,不能只看标称的纠错位数,还要看三个条件:器件预期的工作温度、产品要求的数据保持时间、以及允许的错误率上限。这三个条件越苛刻,对 ECC 能力与固件刷新策略的要求就越高。
坏块管理是 ECC 的孪生机制。NAND 出厂时就存在不可用块,使用过程中还会新增坏块,控制器通过坏块表把坏块从可用地址空间里剔除,并用预留块替换。
| 坏块类型 | 产生时机 | 控制器处理方式 | 主机是否可见 |
|---|---|---|---|
| 出厂坏块 | 制造阶段 | 出厂扫描后写入坏块表 | 不可见 |
| 使用中新增坏块 | 擦写或编程失败时 | 动态标记并替换到预留块 | 不可见 |
| 预留替换块 | 出厂时预留 | 作为替换资源池 | 不可见 |
| 替换余量耗尽 | 长期使用后 | 可用容量下降甚至写保护 | 表现为容量或写入异常 |
表 4-2 · 坏块类型与控制器的处理方式
坏块管理有一个容易被忽略的时间维度:坏块不是只在出厂时存在,而是在整个生命周期里持续产生。前期产生速度慢,随着擦写次数累积会逐步加快。因此预留替换块的消耗速度并不是线性的,评估寿命时应当按「后期加速」来预留余量,而不是按前期速度简单外推。
4.2 磨损均衡与垃圾回收
NAND 的每个块都有擦写次数上限。磨损均衡的目标是让所有块的擦写次数尽量均匀,避免少数热点块提前失效。常见做法分为动态与静态两类:动态策略在写入新数据时挑选擦写次数较低的块;静态策略还会主动搬运长期不动的冷数据,把被长期占用的低磨损块释放出来。
垃圾回收(GC)则是回收无效页占用的空间。NAND 不能就地改写,只能擦除整块后再写入,因此当块内混有无效页和有效页时,控制器必须先把有效页搬走,再擦掉整块。这个「搬移」动作就是写放大的主要来源。
| 写放大的来源 | 机制 | 缓解思路 |
|---|---|---|
| 垃圾回收搬移 | 回收前需搬走块内有效数据 | 保持一定空闲块比例,避免写满 |
| 随机小写 | 小数据反复写同一逻辑区 | 合并成较大的连续写,减少碎片 |
| 映射表元数据回写 | 映射表本身也要落盘 | 由固件策略决定,主机侧影响有限 |
| 文件系统层放大 | 日志、分配表频繁更新 | 选择对 Flash 友好的文件系统与挂载参数 |
| 预留空间不足 | 可用块太少时回收更频繁 | 避免把器件用到接近满容量 |
表 4-3 · 写放大的主要来源与缓解思路
回收动作与业务写入之间的关系,可以概括成一句话:器件越空闲,回收越从容;器件越接近写满,回收越狼狈。当空闲块充足时,控制器可以在后台慢慢搬移;当空闲块紧张时,每一次写入都可能被迫先执行一次紧急回收,延迟与写放大同时上升。这就是「不要写满」这条建议背后的机制。
写放大系数并不是器件自带的固定值,主机的写入模式会显著影响它。持续随机小写、把器件用到接近满容量、频繁更新小文件元数据,都会让回收更频繁,进而放大实际写入量、缩短寿命并降低稳态速度。
反过来说,保持一定的空闲空间、尽量做较大的连续写、减少不必要的元数据刷新,是主机侧能做的、性价比最高的三件事。
4.3 地址映射与掉电保护
地址映射是 FTL 的核心:主机访问的是逻辑块地址,器件内部把它翻译成物理页地址。这个映射表本身也要存放在 NAND 上,并且需要在掉电后能被恢复,因此映射表的更新策略直接决定了掉电后的数据一致性与启动时间。
掉电保护则是另一个层面的事。控制器可以检测电压跌落,并尽力完成已经在处理的写入操作,同时把关键的映射表元数据落盘。但这里有一个必须讲清楚的边界:器件内部的掉电保护只能保护它自己已经接管的那一层,无法保证上层文件系统结构的一致性。
| 机制 | 控制器负责的部分 | 主机仍需负责的部分 |
|---|---|---|
| 地址映射 | 逻辑到物理映射的维护与恢复 | 无需关心 |
| 映射表落盘 | 关键元数据在掉电前尽量落定 | 无需关心,但需保证供电时序 |
| 电压跌落检测 | 检测并触发紧急处理流程 | 提供足够的掉电预警时间与储能 |
| 在手写入完成 | 尽力完成已接收的写入 | 不要期望它覆盖所有情况 |
| 文件系统一致性 | 不涉及 | 日志、分配表、目录结构由主机保证 |
| 掉电时机控制 | 不涉及 | 确保不在写入过程中断电 |
表 4-4 · 掉电保护的责任边界划分(最容易被误解的一张表)
还有一个容易被追问的问题:既然这六件事都由器件内部完成,主机到底能不能感知到它们?答案是:绝大多数时候感知不到,只有结果能被观察到。理解这一点,可以避免把「器件内部正在回收」误判成「器件坏了」。
| 事项 | 主机是否可见 | 可见的表现 | 不可见的原因 |
|---|---|---|---|
| ECC 纠错 | 不可见 | 只在纠错失败时才报错 | 整个过程在器件内部完成 |
| 坏块替换 | 不可见 | 可用容量不变,无报错 | 替换在预留块内悄悄完成 |
| 磨损均衡 | 不可见 | 没有直接表现 | 属于固件内部的调度策略 |
| 垃圾回收 | 间接可见 | 表现为写入延迟上升 | 影响体现在时间而非接口 |
| 地址映射 | 不可见 | 主机只给逻辑地址 | 映射表保存在器件内部 |
| 掉电保护 | 部分可见 | 唤醒后可能出现状态异常 | 只有结果能被观察到 |
表 4-5 · 六件事对主机的可见性对照
正因为大多数动作不可见,现场才容易出现一种典型的误判:把器件内部正在进行的正常回收,当成器件发生了故障。表现是写入延迟突然升高、吞吐短时下降,但没有任何错误上报。区分这两者的实用方法是看「延迟升高是否可恢复」——回收导致的升高会在空闲一段时间后回落,而真正的故障通常伴随错误码或不可恢复的卡死。