适用人群:目标江波龙 firmware 岗,知道 NAND 有坏块、要 ECC,但被问"FTL 是干嘛的、磨损均衡怎么实现、垃圾回收搬的是什么、掉电写到一半怎么办"就答不上来的同学。这是 17_存储 专栏第三篇,也是存储原厂 firmware 岗的面试核心
读完你能得到:
① 为什么 NAND 必须套一层 FTL 才能当"硬盘"用;
② FTL 四大功能:地址映射 / 磨损均衡 / 垃圾回收 / 坏块管理;
③ 页映射 vs 块映射 vs 混合映射的取舍;
④ 异地更新、磨损均衡(动态/静态)、GC 搬页的逻辑;
⑤ 掉电保护在 FTL 里怎么落地(映射表持久化 + 原子切换);
⑥ 一段极简 FTL 写路径思路(面试能口述)。


一、为什么需要 FTL

NAND 原生有几条"反人类"特性(存储_02 讲过):

  1. 写前必擦,而且擦的单位(块)比写(页)大
  2. 不能原地改(写只能 1→0);
  3. 有坏块,不能存数据;
  4. 寿命有限(P/E 次数),得摊着用。

如果直接把 NAND 暴露给上层(文件系统/应用),上层会崩溃——“我想改这个字节"在 NAND 上根本做不到。于是加一层软件/固件:FTL(Flash Translation Layer,闪存转换层),在 NAND 和上层之间做翻译,让上层以为自己在操作一块"普通硬盘”。

  文件系统 / 应用
        │  以为在读写"逻辑块 LBA"
        ▼
   ┌──────────────┐
   │     FTL       │  ← 江波龙这类厂自研的核心固件
   │ 映射+均衡+GC+BBM│
   └──────────────┘
        │  实际操作"物理页/块 PPA"
        ▼
      NAND Flash

一句话:FTL 就是"把难用的 NAND 伪装成好用的块设备"的那层固件。eMMC/UFS/SSD 内部的控制器里跑的就是它——这也是江波龙这种原厂的核心技术壁垒。


二、FTL 四大功能

功能 解决什么 怎么做的
① 地址映射 上层逻辑地址 ↔ 物理地址 维护映射表 LBA→PPA
② 磨损均衡 所有块擦写次数均匀,延长寿命 动态+静态均衡
③ 垃圾回收 GC 回收"无效页"占用的块 搬有效页、擦无效块
④ 坏块管理 BBM 跳过坏块、替换保留块 坏块表 + 重映射

四件里,地址映射是地基,后三件是 NAND 专用的"续命"手段


三、地址映射:LBA → PPA

上层给的是逻辑块地址 LBA(第几个逻辑扇区),FTL 翻译成物理页地址 PPA(实际存在 NAND 的哪一页)。

  写 LBA=5 的数据:
    查映射表:LBA 5 → PPA (block 3, page 7)
    实际写到 (3,7)
  读 LBA=5:
    查表 → (3,7) → 从 NAND 读那页

3.1 三种映射粒度

类型 映射单位 表大小 灵活度 特点
页映射 逻辑页↔物理页 大(表项=页数) 最高 随机写性能好,但 RAM 占用大
块映射 逻辑块↔物理块 小(表项=块数) 省 RAM,但随机写要整块搬,慢
混合映射 数据块(块映射)+日志块(页映射) 折中,消费级常用

面试常问"映射表存哪":一部分常驻 RAM(快查),完整版存在 NAND 的 spare/专用区,掉电时能恢复(见第五节)。


四、异地更新 + 垃圾回收

4.1 异地更新(Out-of-Place Write)

因为不能原地改,更新一个逻辑页时,FTL 写到新的物理页,把旧的标记为"无效":

  初始:LBA 5 → PPA (3,7)   [有效]
  更新 LBA 5:
     写到新页 (4,2),改映射 LBA 5 → (4,2)
     旧页 (3,7) 标记为无效(invalid)

无效页越来越多,块里有效页变少,得回收。

4.2 垃圾回收 GC

GC 选一个有效页最少的块(victim),把里面还有用的有效页搬到别处,然后整块擦除重用:

  选 victim 块 B:含 3 个有效页 + 5 个无效页
     把 3 个有效页复制到空闲块
     擦除 B(现在全 1,可再写)

触发时机:空间不足时强制 GC,或空闲时后台 GC(不卡前台)。GC 会带来写放大(见 存储_02),好的 FTL 要减少无效搬运。


五、磨损均衡(Wear Leveling)

5.1 为什么

如果某个逻辑块被频繁写,它对应的物理块很快到寿命。磨损均衡的目标:让所有块的擦写次数尽量平均,整体寿命最大化。

5.2 动态 vs 静态

类型 做法 解决
动态均衡 只在"被重写/重分配"的块间均衡 频繁写的"热"块均匀耗损
静态均衡 很少改的"冷"数据也搬出来,让冷块也能被擦写 防止冷块永远不擦、热块先死

静态均衡是关键:如果不管冷数据,冷块永远 0 次擦写、热块早早报废,整体寿命起不来。好的 FTL 冷数据也要定期搬


六、坏块管理(BBM)

存储_02 的坏块:FTL 维护一张坏块表

  上电:扫所有块 OOB 区,建立初始坏块表(出厂坏块)
  运行中:写/擦失败 → 标记新坏块 → 从"保留块池"分配替换块
  以后映射时:跳过坏块表里的块

保留块(spare/reserved blocks)是出厂时多留的冗余,专门替补坏块。坏块率在设计冗余度里就考虑进去了。


七、掉电保护:FTL 层面的"原子性"

这是车规/消费都卡死的一关。问题:GC 搬页、改映射表的过程中掉电,数据怎么办?

FTL 的做法:

  1. 映射表持久化:定期把映射表写回 NAND 专用区,掉电后能恢复大部分;
  2. 原子切换:更新数据时,先写完新页 + 新映射(存在临时区),最后一步才把"指向新映射"的指针翻过来。翻指针前掉电 → 回滚到旧版本;翻之后掉电 → 新版本已生效。中间状态不对外可见;
  3. 事务/日志(journal):像数据库一样,操作先记日志再执行,崩溃后重放或回滚。

这和你 07_OTA 的"双 bank + 标志位切换"是同一思想:用"写完再翻指针"保证要么旧要么新、没有半成品。江波龙车规产品对掉电保护要求极高(AEC-Q100),这块是必考点。


八、一段极简 FTL 写路径(面试可口述)

/* 伪代码:写逻辑块 LBA */
ftl_write(lba, data):
    ppa_new = alloc_free_page()        // 从空闲页池拿一页
    nand_program(ppa_new, data)        // 写到新页(异地更新)
    ppa_old = map[lba]                 // 旧物理页
    map[lba] = ppa_new                 // 改映射
    mark_invalid(ppa_old)              // 旧页标记无效
    if (need_wear_leveling())          // 某块擦写次数过高
        wear_level_one_block()         // 均衡一次
    if (free_pages < threshold)        // 空闲页不够
        gc_one_block()                 // 回收一个块
    if (power_loss_risk())             // 电压低/要掉电
        flush_mapping_table()          // 持久化映射表(原子切换)

口述时把"异地更新→标记旧无效→GC 回收→磨损均衡→掉电刷表"这条链讲顺,考官基本就认可你懂 FTL 了。


九、为什么江波龙要自研 FTL

FTL 算法直接决定三件事:

  • 性能:映射粒度、GC 策略影响读写延迟;
  • 寿命:磨损均衡好坏决定 NAND 能用几年;
  • 可靠性:掉电保护、坏块管理决定数据会不会丢。

同样一颗 NAND,不同 FTL 跑出来寿命和速度差几倍——所以存储原厂的 FTL 是核心技术资产,必须自研、不能买现成。这就是你投江波龙 firmware 岗要懂 FTL 的根本原因。


十、面试速答

考官:FTL 是干嘛的?
:NAND 不能原地改、擦单位大、有坏块、寿命有限,不能直接当硬盘用。FTL 在 NAND 和上层之间做翻译,提供四大功能:地址映射、磨损均衡、垃圾回收、坏块管理,让上层以为在读写普通块设备。eMMC/UFS/SSD 控制器里跑的就是它。

考官:磨损均衡怎么实现?
:分动态和静态。动态只在被重写的块间均衡擦写次数;静态还会把很少改的冷数据搬出来,让冷块也能被擦写,防止热块先报废、整体寿命最大化。

考官:掉电写到一半怎么办?
:FTL 用异地更新+原子切换——数据先写新页,最后一步翻映射指针才生效,翻之前掉电回滚旧版、之后掉电是新版,没有半成品;映射表也会定期持久化。


十一、总结

要点 内容
FTL 作用 把 NAND 伪装成块设备,四大功能
映射 LBA→PPA,页/块/混合三种粒度
异地更新 更新写新页、旧页标记无效
GC 搬有效页、擦无效块,有写放大
磨损均衡 动态+静态,所有块擦写趋平均
BBM 坏块表+保留块替补
掉电保护 映射表持久化+原子切换

一句话总结:FTL 是 NAND 的"操作系统"——用地址映射承接上层、用异地更新+GC 管理空间、用磨损均衡延长寿命、用坏块管理避开坏区、用原子切换扛掉电,四件套缺一不可,也是存储原厂 firmware 的核心竞争力。


FTL 算法细节(如 DFTL、FAST 等学术论文方案)以各厂实现为准,本文讲通用四件套与工程取舍。映射表 RAM/NAND 分工、保留块比例等都因器件容量而异。
本站相关:存储_02(NAND 坏块/ECC/寿命)、07_固件升级与OTA(双 bank 原子切换)、存储_05(掉电保护深入)。


下一篇:存储_04_接口与协议——SPI_NOR_QSPI与SDIO_eMMC命令

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐