4. eMMC内部管理机制
eMMC 对主机呈现的是一个线性的逻辑块地址空间(LBA),但内部真正的存储介质是 NAND Flash。NAND 的物理特性决定了它不能像 RAM 那样随意覆盖写:每个存储单元在写入前必须处于擦除状态,而擦除的最小单位是块(Block),写入的最小单位是页(Page)。为了让主机能够像使用普通块设备一样读写 eMMC,控制器内部必须运行一套完整的 Flash 管理机制,其中 FTL 映射、磨损均衡、垃圾回收、坏块管理与读写放大是五个相互耦合的核心环节。
一、FTL 映射:逻辑地址到物理地址的翻译层
FTL(Flash Translation Layer,闪存转换层)是 eMMC 内部固件的核心。它维护一张映射表,把主机下发的逻辑页地址(LPN)翻译为 NAND 中的物理页地址(PPN)。当主机覆盖写某个逻辑页时,FTL 并不会原地改写旧物理页,而是把新数据写入一个空闲物理页,然后更新映射表,使该逻辑页指向新的物理页,旧物理页被标记为“无效”。
映射粒度通常分为页级映射、块级映射和混合映射。页级映射灵活但映射表庞大,需要占用较多 SRAM 或借助 NAND 存放;块级映射表小,但小文件随机写性能差;混合映射在两者之间折中,是消费级 eMMC 常见方案。映射表本身也需要持久化,通常以日志或快照方式写入 NAND,并在上电时重建。
二、磨损均衡:让每个块被均匀擦写
NAND 块的擦写寿命有限,SLC 约 10 万次,MLC 约 3000 次,TLC 约 1000 次甚至更低。如果总是反复擦写同一批物理块,这些块会提前失效,整颗 eMMC 的寿命被短板决定。磨损均衡(Wear Leveling)的目标就是让擦写操作尽量均匀分布到所有可用块上。
磨损均衡分为动态和静态两类。动态磨损均衡只在有新数据写入时,优先选择擦写次数少的空闲块;静态磨损均衡则会主动搬移长期不被修改的“冷数据”,把低擦写次数的块释放出来供热数据使用。静态磨损均衡会带来额外的数据搬移,因此需要与垃圾回收协同调度。
三、垃圾回收:回收无效页,制造可用块
随着覆盖写不断发生,NAND 中会产生大量“部分有效、部分无效”的块。垃圾回收(Garbage Collection,GC)的任务是选择一个 victim 块,把其中仍然有效的页复制到新的空闲块,然后擦除 victim 块,使其重新变为可写块。GC 是 eMMC 后台最重要的维护操作,也是写放大和写延迟抖动的主要来源。
GC 的触发时机通常包括:空闲块数量低于阈值、写入请求到来但没有可用块、后台空闲时主动回收。前台 GC 会阻塞主机写入,导致延迟升高;后台 GC 则利用空闲时间提前整理。好的固件会在空闲块水位、GC 效率和主机延迟之间做动态平衡。
四、坏块管理:从出厂坏块到增长坏块
NAND 在出厂时就可能存在坏块,使用过程中也会因擦写磨损、编程干扰、读干扰等原因产生新的坏块。坏块管理包括坏块标记、坏块替换和坏块表维护。出厂坏块通常在测试阶段被标记,并预留一定比例的备用块(spare blocks)。当某个块被判定为坏块后,FTL 会把它从可用块池中移除,并用备用块顶替。
坏块判定依据包括编程失败、擦除失败、ECC 纠错失败、读干扰超限等。对于 eMMC 而言,坏块管理对主机是透明的,主机看到的仍然是连续的 LBA 空间,但实际可用容量会因备用块消耗而逐渐减少。
五、读写放大:性能与寿命的隐形税
读写放大(Write Amplification,WA)是指实际写入 NAND 的数据量大于主机请求写入的数据量。其来源主要有三部分:一是 GC 搬移有效页产生的额外写入;二是映射表、日志、元数据的更新;三是对齐和合并操作。写放大系数 WA = NAND 实际写入量 / 主机写入量,理想情况下接近 1,实际中可能达到 2~5 甚至更高。
写放大直接消耗 NAND 擦写寿命,也占用内部带宽,导致写入性能下降。降低写放大的手段包括:提高顺序写比例、减少小随机写、合理设置预留空间(OP)、优化 GC victim 选择策略、以及让主机文件系统发送 discard/trim 命令及时告知无效数据。
六、机制协同与典型场景
这五个机制不是独立运行的。FTL 决定新数据写到哪里,磨损均衡决定选哪个块,GC 决定何时搬移和擦除,坏块管理决定哪些块还能用,而读写放大则是它们共同作用的结果。以一段持续的小文件随机写为例:主机不断覆盖写同一批逻辑页,FTL 不断分配新物理页,旧页变成无效页;空闲块快速消耗,GC 被频繁触发,搬移大量有效页;写放大升高,NAND 擦写次数增加,坏块风险上升,备用块被消耗。最终表现为写入速度下降、设备寿命缩短。
| 机制 | 核心作用 | 关键输入 | 对读写放大的影响 | 可靠性风险 |
|---|---|---|---|---|
| FTL 映射 | 逻辑地址到物理地址翻译 | LPN、映射表、空闲页 | 映射表更新带来额外写入 | 映射表损坏导致数据不可寻址 |
| 磨损均衡 | 均匀分布擦写次数 | 块擦写计数、冷热数据 | 静态均衡搬移冷数据,增加写入 | 局部块提前耗尽,寿命短板 |
| 垃圾回收 | 回收无效页,释放空闲块 | victim 块、有效页比例 | 主要写放大来源,可达数倍 | 前台 GC 导致写延迟抖动 |
| 坏块管理 | 隔离坏块,备用块替换 | ECC 结果、擦写状态 | 备用块消耗,可用容量下降 | 坏块表丢失或备用块耗尽 |
| 读写放大 | 衡量实际写入与主机写入之比 | GC 搬移量、元数据量 | 本身是结果指标 | 高 WA 加速寿命消耗 |
七、常见误区与复盘
误区一:认为 eMMC 是“黑盒”,主机写多少 NAND 就写多少。实际上 GC 和元数据会带来显著写放大,主机写入 1GB,NAND 可能写入 3GB 以上。
误区二:认为坏块只存在于出厂阶段。使用过程中擦写磨损、读干扰、编程干扰都会产生增长坏块,备用块会被逐渐消耗。
误区三:认为 discard/trim 只是“建议”。及时下发 discard 可以让 FTL 提前知道哪些逻辑页已无效,显著降低 GC 搬移量,是降低写放大的有效手段。
工程实践中,评估 eMMC 可靠性不能只看标称擦写次数,还要关注:顺序写与随机写的比例、文件系统是否支持 discard、预留空间 OP 是否充足、GC 策略是否偏向低延迟、以及坏块增长速率。建议在压力测试中同时记录主机写入量、NAND 写入量、GC 次数和备用块消耗,用数据判断写放大和寿命余量。
# 查看 eMMC 健康与寿命信息的典型思路(以 Linux 为例)
cat /sys/block/mmcblk0/device/life_time # 寿命等级 A/B
cat /sys/block/mmcblk0/device/pre_eol_info # 接近寿命终点提示
cat /sys/block/mmcblk0/device/health_status # 健康状态
# 关注字段:EXT_CSD 中的 DEVICE_LIFE_TIME_EST、PRE_EOL_INFO
# 结合 fio 压测记录 host write 与 device write,估算写放大
理解 FTL、磨损均衡、垃圾回收、坏块管理和读写放大之间的耦合关系,是设计高可靠 eMMC 存储方案的基础。只有把主机写入模式、文件系统行为和 eMMC 内部策略放在一起考虑,才能在性能、寿命和成本之间取得平衡。