闪存控制器(Flash Controller)是位于主机和 NAND Flash 之间的控制逻辑,负责把主机的块读写请求转换成 NAND 的 page/program/erase 操作,并处理 FTL(闪存转换层)、ECC(错误纠正码)、磨损均衡 和 坏块管理。
在 eMMC 和 UFS 里,闪存控制器通常封装在存储芯片内部;在裸 NAND 方案里,控制逻辑可能由 SoC 内的 NAND 控制器、驱动和文件系统共同承担。
核心问题
主机希望看到稳定、连续、可重复读写的逻辑块设备;NAND Flash 提供的是有擦除粒度、错误率、坏块和寿命限制的物理介质。
闪存控制器解决的是这两者之间的落差:
- 把 LBA 映射到实际 NAND page。
- 对读出数据做 ECC 校验和纠错。
- 避免某些 block 被写坏,执行磨损均衡。
- 遇到坏块时迁移数据并重映射。
- 在掉电、垃圾回收和后台搬迁中尽量保持一致性。
- 调度多 die / multi-plane / cache program 等并行能力。
核心对象
| 对象 | 作用 | 工程关注点 |
|---|---|---|
| host interface | 面向主机的协议接口 | eMMC、UFS、SATA、NVMe、SPI NAND |
| NAND interface | 面向闪存颗粒的物理/命令接口 | 时序、通道数、die 数、并行度 |
| mapping table | 逻辑到物理地址映射 | 粒度、缓存、掉电恢复 |
| ECC engine | 错误检测和纠正单元 | BCH、LDPC、纠错能力、延迟 |
| wear-leveling engine | 磨损均衡逻辑 | erase count、冷热数据分离 |
| bad-block table | 坏块记录 | 出厂坏块、增长坏块、替换块 |
| buffer / cache | 控制器内部 SRAM/DRAM | 写缓存、掉电保护、一致性 |
核心机制
一次写请求可以抽象为:
host write(LBA, data)
-> choose physical_page
-> encode data + ECC
-> program NAND page
-> update mapping_table[LBA]LBA是主机看到的逻辑块地址。physical_page是控制器选择的实际 NAND page。encode data + ECC会为数据生成校验冗余,读回时用于纠错。update mapping_table是关键一致性步骤;如果掉电发生在这里,控制器要能恢复到旧映射或新映射之一。
读请求则是:
physical_page = mapping_table[LBA]
raw = read NAND physical_page
data = ECC_decode(raw)如果 ECC 可纠正错误,主机通常感知不到;如果错误超过纠错能力,就可能返回 I/O error 或触发内部数据搬迁。
工程用途
- 让 eMMC/UFS/SSD 对上层系统表现为块设备。
- 隐藏 NAND 复杂性,降低 Bootloader、kernel 和文件系统负担。
- 提供寿命估计、错误计数、健康状态和安全区域访问能力。
- 支持启动分区、RPMB、discard/TRIM、sanitize 等管理功能。
工程调试时要看主机侧日志、设备健康指标、I/O error、写入延迟毛刺、掉电一致性和是否正确使用 discard 或只读系统分区策略。
边界与常见坑
- 控制器隐藏了细节但不消除物理限制:NAND 仍有寿命、错误率和擦除成本。
- 块设备成功写入不一定马上落到 NAND:可能经过缓存和后台整理,掉电策略很重要。
- 不同厂商控制器行为差异很大:同容量 eMMC 的随机写、寿命和掉电恢复可能差异明显。
- 健康指标不是精确剩余寿命:EXT_CSD 或 SMART 类字段通常是粗粒度估计。
- 裸 NAND 和托管 NAND 诊断方式不同:裸 NAND 需要看 MTD/UBI/ECC 日志;eMMC/UFS 多看块设备和设备寄存器。