只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 电子设计&技术探讨 -> 坏块管理与标记策略_技术探讨

坏块管理与标记策略_技术探讨

同系列 · 原理方案设计
扫码打开本页
微信扫码

坏块管理与标记策略 · 技术探讨

从「什么叫坏块」到「由谁来读这条结论」——把闪存坏块的判定、标记、替换与责任边界讲透的一份工程参考 | 编制日期 2026-10-14 | 版本号 Rev 1.0

1 条主线
坏块不是缺陷,而是闪存的标配
管理的核心是四问:谁判、按什么判据判、写到哪里、由谁读
4 个问题
贯穿全部 12 章的统一框架
判读者 / 判据 / 落点 / 读取方
2 类方案
责任边界完全不同
裸 NAND 主机自管 vs 内置控制器内部吸收
2 段标记
出厂标记与运行时标记
同一条链的前后两段,不是两套互斥机制
报告总结

闪存器件在出厂时就已经带着坏块,使用过程中还会继续产生新的坏块。这件事并不丢人,也不可怕——真正会出问题的是「没人管」或者「管错了人」:裸 NAND 上主机固件以为器件自己会处理,内置控制器方案上主机又想去读一个根本不存在的坏块表,这两种误判在工程现场都相当常见。

这份文档不讲器件物理,也不讲某个厂商的私有算法,只讲工程上必须回答清楚的四个问题:谁判坏、按什么判据判、把结论写到哪里、由谁来读这个结论。围绕这四问,把出厂筛选、运行时判定、标记落点、替换映射、启动场景、寿命预算、故障诊断串成一条完整链路,并明确两种不同的产品形态(裸 NAND 与内置控制器方案)在这条链上完全不同的责任边界。

结论: 坏块不是缺陷,而是闪存的标配。管理的核心永远是四问——谁判、按什么判据判、把结论写到哪里、由谁来读。 裸 NAND 里这四问全部由主机固件自己回答,判据(擦除失败、编程失败、纠错量超限)与标记落点(备用区或集中登记表)都必须由固件设计与维护; 内置控制器方案(SD NAND / eMMC 等)里坏块被控制器完全吸收,四问由控制器内部回答,主机看不到坏块,只能看到预留块消耗与健康度这类替代信号,判据与责任边界因此完全不同。 本文所有阈值、比例与次数均为行业经验区间,实际设计一律以正式 datasheet 与实测为准。

读者路径

  • 先把概念钉清楚:第 1 章(成因与定义)→ 第 2 章(出厂筛选与标记)。
  • 要自己写裸 NAND 的坏块管理:第 3 章(判据)→ 第 4 章(标记落点与原子性)→ 第 5 章(替换与映射)→ 第 6 章(在 FTL 中的位置)。
  • 用 SD NAND / eMMC 这类内置控制器器件:第 7 章(主机能看到什么、不能看到什么)+ 第 8 章(启动场景)。
  • 做寿命与容量预算:第 9 章(坏块增长与替换块预算)。
  • 现场出了问题:第 10 章(按现象诊断)+ 附录 C(排查手册)。
  • 只要速查表:第 12 章 + 附录 A(术语)+ 附录 B(标记与判据速查)。

1. 坏块的成因与定义

这一章先把「坏块」这个词钉死。工程现场大量的沟通事故,都来自把三种不同口径的「坏块」混着说。本章要给出的结论是:坏块本质上是一条管理结论,而不是器件的物理属性描述——这个判断决定了后面所有章节的展开方式。

坏块从生成到被标记:一条完整的生命周期链① 缺陷产生出厂工艺离散使用期单元退化② 失败被观测擦除 / 编程 / 读取报出失败或超限③ 判坏决策重试与复核之后确认不可恢复④ 写入标记备用区或登记表留下可复查结论⑤ 建立替换从替换池取块登记映射关系⑥ 上层屏蔽地址翻译之后主机只见好块读法:整条链只回答四个问题谁判:裸 NAND 由主机固件判;内置控制器方案由控制器内部判,主机不参与,也拿不到原始结论。按什么判据判:事件型(擦除 / 编程失败)与阈值型(纠错量超限)两大类,二者的重试与复核策略不同。写到哪里、由谁读:标记必须落在一个「判读者下次上电还能找到」的位置,否则这条链当场断掉。
图 1 · 坏块从生成到被标记:一条完整的生命周期链

1.1 什么叫坏块:从「读不出正确数据」说起

「坏块就是读不出正确数据的块」——这句话在工程上不够用,因为它把三件完全不同的事混成了一个词。实际沟通里至少有三种口径在同时使用:

  • 物理口径:块内的部分存储单元已经不能可靠地保持电荷,或者阈值电压已经漂出了可读窗口。
  • 操作口径:对这个块执行擦除、编程、读取时,器件返回了失败状态,或者纠错之后的结果超出了约定的可靠度。
  • 管理口径:固件或控制器已经把它登记进坏块表,后续不再向它分配任何用户数据。

真正驱动系统设计的是第三种口径。前两种只是输入。一个块即使物理上已经很差,只要还没有被登记,上层就照样会把数据写进去;反过来,一个块一旦被登记,哪怕它实际上还能读出数据,也不会再被分配。坏块是一条管理结论,不是一条物理测量结论。

这也是为什么「读不出正确数据」这个起点说法需要修正:现代闪存几乎都带纠错,一次读取出原始 bit 错误是常态,不是故障。真正的起点是「纠错之后的可靠度不再满足约定」——也就是说,坏不坏不是看有没有错,而是看错到什么程度、用多大代价才补得回来。

口径判据来源谁能得到这个结论对系统的直接影响常见误用
物理口径阈值分布 / 保持力 / 漏电器件物理层,主机一般不可见无直接影响,只作为失效分析输入拿它去解释运行时故障
操作口径擦除、编程、读取的返回状态与纠错量发起操作的一方(主机固件或控制器)触发重试、复核与判坏流程把单次失败直接当成判坏
管理口径坏块登记表里是否存在该块坏块表的持有者决定地址分配与容量可见性以为表里有就一定物理损坏

把这三种口径分开之后,很多争论会立刻消失。例如「这个块明明还能读,为什么要判坏」——答案是:判坏决策依据的是纠错余量已经不足以支撑下一次可靠读取,而不是「现在能不能读出来」。再例如「出厂报告说没有坏块,为什么用着用着就有了」——答案是:出厂报告是某一时刻的管理结论,不是永久保证。

1.2 出厂坏块与运行时坏块

按产生时点分,坏块只有两类:出厂坏块与运行时坏块。这个分类之所以重要,不是因为它们物理成因不同(其实高度重叠),而是因为判读者、标记落点、可信度完全不一样。

  • 出厂坏块:器件在出厂前由原厂筛选出来,并把结论以某种约定写在器件内部。它的判读者是原厂的测试程序,标记在主机第一次上电之前就已经存在。
  • 运行时坏块:器件交付之后,在实际使用中因擦写磨损、干扰、保持力退化等原因被判坏。它的判读者是使用方(主机固件或内置控制器),标记是在现场写下去的。

两者的关键差别在于「谁承担误判的后果」。出厂判坏判重了,代价是原厂少卖一点可用容量;出厂判坏判轻了,代价是客户现场启动失败。而运行时判坏判重了,代价是替换块被白白消耗;判轻了,代价是数据静默损坏。两种场景的代价结构完全相反,这直接决定了判据的宽松程度。

对比维度出厂坏块运行时坏块
产生时点器件交付之前器件交付之后的使用过程中
判读者原厂测试程序主机固件(裸 NAND)或内置控制器
判据原厂筛选流程定义的失效门限擦除 / 编程失败事件,或纠错量越限
标记落点备用区就地标记,或首个块内的坏块表就地标记 + 集中登记表(双写居多)
标记写入者原厂设备现场固件 / 控制器
可信度较高,但仍是某一时刻的结论取决于判据与重试策略是否充分
误判代价判重:可用容量减少;判轻:现场启动失败判重:替换块被浪费;判轻:数据静默损坏
主机是否可见裸 NAND 可见;内置控制器方案不可见裸 NAND 可见;内置控制器方案不可见
一个容易踩的坑

不要以为「出厂坏块表是绝对真理」。它记录的是出厂那一刻筛选流程得出的结论,筛选流程本身有门限,门限之上判坏、门限之下放行。那些「刚好在门限之下」的块,往往就是现场最先退化的一批。出厂标记解决的是「已知问题」,不是「未来问题」。

1.3 坏块的物理成因分类

从工程处置的角度看,成因不需要细分到半导体物理层面,分成四类就够用了。分类的意义在于:不同成因对应不同的判据与不同的处置动作,胡乱套用会造成大量误判或漏判。

  • 工艺与结构缺陷:栅氧缺陷、短路、开路这类硬伤。特点是一出生就有,而且不可恢复,出厂筛选能拦下绝大部分。
  • 擦写磨损:隧穿氧化层在反复擦写中疲劳,绝缘能力下降,保持力逐步变差。特点是随擦写次数单调累积,可预测但不可逆转。
  • 编程干扰与读干扰:对相邻单元编程、或者对同一块内其它页反复读取,会扰动未操作单元的电荷。特点是多数情况下擦除一次就能恢复,因此绝不能一发现就判坏。
  • 电荷保持失效:单元漏电导致阈值随时间漂移,高温会显著加速。特点是与存放时间强相关,断电存放越久越容易暴露。
成因类别典型机理是否可恢复主要暴露时点对应的处置动作
工艺与结构缺陷栅氧缺陷、短路、开路不可恢复出厂筛选、首次上电扫描直接判坏并替换,无需重试
擦写磨损隧穿层疲劳、保持力下降不可恢复擦写次数接近寿命末期判坏并替换,同时计入寿命统计
编程 / 读干扰相邻单元扰动、读串扰多数可经擦除恢复正常使用中随机出现先重试与复核,确认不可恢复才判坏
电荷保持失效漏电导致阈值漂移取决于漂移程度长时间断电存放后、高温环境以纠错量越限为判据,判坏前先复核
成因决定判据:前两类偏结构性,后两类偏使用性工艺与结构缺陷栅氧缺陷、短路早期失效为主出厂筛选剔除擦写磨损隧穿层疲劳保持力逐步下降随擦写次数累积编程与读干扰相邻单元扰动读干扰逐步累积多数可擦后恢复电荷保持失效阈值漂移越界高温下明显加速与存放时间相关为什么成因分类对坏块管理有用前两类偏「结构性」,出厂筛选能拦下大部分;后两类偏「使用性」,只能靠运行时判据兜住。因此出厂标记与运行时标记不是两套互斥机制,而是同一条链上前后相接的两段。判据的可信度取决于成因:结构性缺陷判一次即可,使用性退化必须留出重试与复核。
图 2 · 坏块的四类物理成因与各自的处置取向

1.4 坏块率与工艺、容量、叠层数的关系

坏块率不是一个可以脱离器件形态讨论的常数。它随四个方向变化,而且变化的方向在工程上是可预期的,即使具体数值必须以正式 datasheet 为准。

  • 工艺微缩:单元尺寸变小,单个存储单元能容纳的电子数变少,阈值电压分布的相对展宽变大,判读窗口变窄,出错概率上升。
  • 容量增大:即使单个块的失效率不变,单元总数增加也会让「至少出现一个坏块」的概率明显上升。这就是为什么大容量器件几乎不可能零坏块。
  • 叠层数增加:同一片器件里垂直堆叠更多层,工艺一致性的控制难度上升,层间离散会带来额外的早期失效。
  • 每单元位数增加:从每单元 1 位到多位,阈值窗口被切成更多份,每份的宽度更窄,对漂移与干扰的容忍度更低。

把这四条合起来,可以得到一条对工程有用的判断:越是大容量、高层数、高位密度的器件,越不能假设「没有坏块」。反过来说,小容量、成熟工艺、每单元位数少的器件,出厂坏块的比例通常处在很低的水平,但这依然不等于零。

变量方向对坏块率的影响机理工程上的应对备注
工艺越微缩上升单单元电子数减少,阈值分布展宽判读余量收紧,纠错能力要更强具体门限以 datasheet 为准
容量越大出现坏块的概率上升单元总数增加,基数变大替换块池按容量比例预留大容量器件零坏块不现实
叠层越多上升层间工艺一致性难度上升出厂筛选更依赖原厂流程与具体堆叠工艺相关
每单元位数越多上升阈值窗口被切得更窄读判据更依赖纠错量与重试SLC / MLC / TLC / QLC 差异明显

还有一条常被忽略的推论:坏块率的变化并不改变坏块管理的必要性,只改变它的规模。工艺进步让单位容量的坏块率下降,但同期容量增长得更快,二者相抵之后,一颗器件上坏块的绝对数量通常是上升而不是下降的。因此「新工艺更可靠,所以可以少留替换块」是一个危险的想法。

对工程实践更有用的是把坏块率拆成两个量来看:单个块的失效率与整片出现坏块的概率。前者决定了运行时判坏的频率,后者决定了出厂阶段必须准备多少替换块。只盯着其中一个,都会做出错误的预算。

此外还需要注意批次离散:同一型号不同批次的坏块比例可能相差不少。因此容量预算不能只按一颗样品来定,而应当按规格书给出的上限来定,再用实测数据确认自己拿到的批次处在什么位置。

这里不给出具体坏块率数字的理由

坏块率与「什么算一个坏块」的定义强绑定:有的原厂按块统计,有的按单元统计;有的把可纠错的块也算进去,有的不算。脱离定义谈数字没有意义,而定义又写在各家器件手册里。本文只给方向性判断,实际做容量预算时请直接引用所用器件的正式规格。

1.5 为什么坏块管理是标配而不是补丁

把坏块管理当成「器件坏了之后才需要的东西」,是裸 NAND 方案里最常见、代价也最高的误解。坏块管理之所以是标配,有三个很硬的理由。

  • 出厂就带坏块是常态,不是异常:只要器件容量做到一定规模,零坏块在统计上就不可能稳定成立。因此上电第一件事必须是「读出厂坏块表」,而不是假设介质是好的。
  • 启动代码所在的位置不能赌:启动映像如果落在坏块上,器件不是「性能下降」,而是直接变砖。这个后果的严重性决定了坏块管理必须在启动链路的最前端就位。
  • 运行时坏块的产生是确定的,只是时点不确定:擦写磨损一定会发生,坏块一定会增长。问题不是「会不会有」,而是「什么时候有、有没有人接得住」。
设计取向把坏块管理当补丁把坏块管理当标配
上电初始化直接挂载文件系统,出错再说先读出厂坏块表,再建立可用块视图
启动映像写在一个固定偏移,赌它不是坏块冗余副本 + 启动前校验,坏块可跳过
运行时失败返回错误码给上层,由应用处理固件内部重试、复核、判坏、替换、登记
替换块没有预留,坏了就少一块容量按比例预留替换池,耗尽才算寿命终了
容量可见性标称容量即实际可用容量可用容量 = 标称容量减去出厂坏块与预留
典型后果偶发变砖、静默数据损坏容量略降,但行为可预期

1.6 本文要回答的问题与主线

全文围绕四个问题展开。这四个问题不是并列关系,而是一条链上的四个环节,任何一个环节答错,整条链就断了。

  1. 谁判:判坏这个动作由谁执行?裸 NAND 上由主机固件执行;内置控制器方案上由控制器内部执行。
  2. 按什么判据判:事件型判据(擦除失败、编程失败)与阈值型判据(纠错量超限)各自适用什么场景,判坏之前要不要重试、重试几次。
  3. 把结论写到哪里:就地写在块的备用区,还是集中写到一张登记表?两者如何互相校验,掉电中断时怎么保持一致性。
  4. 由谁来读:这份结论下次上电由谁读取、在什么时机读取、读取失败时怎么办。

本文的立场很明确:坏块不是缺陷,而是闪存的标配。讨论的重点不是「怎么消灭坏块」(做不到),而是「怎么把坏块的存在约束在一个可预期、可观测、可恢复的范围内」。沿着这条主线,第 2 章讲出厂段,第 3 到 5 章讲运行时段,第 6 到 8 章讲它在不同产品形态与场景下的表现,第 9 到 11 章讲寿命、诊断与工程落地。

四问裸 NAND 的答案内置控制器方案的答案主机能看到什么
谁判主机固件器件内置控制器裸 NAND 能看到;控制器方案看不到
判据擦除 / 编程失败、纠错量超限控制器内部判据,不对外公开控制器方案看不到原始判据
写到哪里备用区就地标记 + 集中登记表控制器内部元数据区控制器方案看不到
由谁读主机固件上电时读取并重建控制器内部读取控制器方案只看到预留块消耗

2. 出厂阶段的坏块筛选与标记

这一章讲的是「主机第一次上电之前,器件里已经发生了什么」。出厂段的核心不是筛选本身,而是筛选结论以什么形式、写在什么位置、能被谁读出来。这一段决定了主机固件上电初始化时必须做什么,也决定了「出厂保证」这四个字到底保证到哪一步。

2.1 出厂筛选做了什么

原厂在器件交付前会跑一整套筛选流程,目的不是挑出「完美的器件」,而是把已知不可用的块找出来并留下记录。流程的具体环节各家不同,但骨架高度一致。

  • 结构性测试:在晶圆或封装阶段剔除硬伤,这类缺陷基本不可恢复。
  • 擦写与读回验证:对块做擦除、编程、读回,检查结果是否符合门限,用来抓保持力与阈值分布的问题。
  • 保持力加速验证:通过高温或其它加速手段,把早期退化提前暴露出来。
  • 判坏并写标记:把超过门限的块判坏,按约定写入标记。
  • 生成坏块表并复核:汇总标记结果,写入约定位置,出货前再复核一遍。
筛选环节要抓的问题判据的性质产出局限
结构性测试短路、开路、栅氧硬伤事件型,一次判定硬伤块清单抓不到使用期退化
擦写与读回验证保持力不足、阈值分布异常阈值型,按门限判定可疑块清单门限之下的边缘块会漏
保持力加速验证早期退化、漏电过大阈值型,加速条件下判定加速条件下的失效块加速条件与现场不完全等价
判坏并写标记汇总上述结论管理动作器件内已写好的标记标记本身要能被正确读出
出货前复核标记写入是否正确管理动作可出货的器件复核只覆盖标记,不覆盖未来
出厂段:从结构性测试到出货前复核的六个阶段阶段 1结构性测试:剔除短路、开路、栅氧硬伤产物:硬伤块清单阶段 2擦写与读回验证:检查保持力与阈值分布产物:可疑块清单阶段 3加速条件验证:把早期退化提前暴露出来产物:加速失效块阶段 4判坏并写入标记:按约定写到备用区或保留区产物:就地标记阶段 5生成坏块表:汇总标记并写入约定位置产物:坏块表阶段 6出货前复核:确认标记与表一致产物:可出货器件
图 3 · 出厂筛选与标记的六个阶段:每一步的产物都是下一步的输入

2.2 标记写在哪里:备用区与保留块

出厂标记必须写在一个「判读者还没读它之前不会被擦掉」的位置。实际可用的位置有三类,各有各的适用条件。

  • 块的备用区(页内附带的额外区域):每个页除了用户数据区,还带一小段备用区。把标记写在块内前几个页的备用区里,是最常见的做法。优点是就地可得——读这个块时顺带就能读到它自己的状态;缺点是它依附于块,块一旦被擦除,标记也一起没了。
  • 保留块 / 首个块:把整片的坏块结论集中写在一两个专门保留的块里。优点是一次读出全部结论;缺点是这个块本身也要保证可靠,而且它一旦损坏就影响全局。
  • 两者并用:就地标记提供就地证据,集中表提供快速全盘视图,互相校验。这是裸 NAND 上最稳健的组合。

选择落点时还有一个容易被忽略的约束:标记所在的区域不能与正常数据区共享擦除单位。如果标记写在一个会被用户数据擦除操作顺带擦掉的位置,那么一次普通写入就可能把坏块结论抹掉。这也是为什么标记通常写在块内最前面几个页的备用区——它们位置固定、容易被找到,而且在启动阶段就能读到。

还有一个现实约束是空间。备用区容量有限,除了坏块标记,通常还要放纠错校验数据与逻辑地址信息。因此在设计标记结构时,必须先确认备用区里还剩多少空间可供自己使用,而不是想写多长就写多长。

存放位置读取代价可靠性依赖优点缺点
块内备用区随块读取,代价低依赖该块前几页未被擦除就地可得,不需要额外扫描块被擦除后标记消失
首个块 / 保留块上电一次读出全部依赖该块自身出厂可靠一次拿到全盘结论单点失效影响全局
两者并用先读表,异常时回查就地标记双份,互相校验恢复能力强,可交叉验证占用额外空间与启动时间
文件系统层记录挂载时读取依赖文件系统自身完整性便于日志与追溯启动阶段还不可用
标记写在哪:主阵列、首个块与替换块池的相对位置整片阵列(每一格代表一个块)首块坏坏替换块池(出厂预留,容量通常不对外暴露)备用备用备用备用备用备用备用备用按需取用用完即止备用区里写了什么:标记不是一个位,而是一段约定标记以「非擦除态的约定图案」写在块内前几个页的备用区,具体图案与位置以器件手册为准。首块承担双重职责:它既要能被启动流程直接读取,又常常兼作整片坏块表的落点。替换块池对主机是否可见,取决于产品形态:裸 NAND 可见,内置控制器方案被完全吸收。因此「标称容量」与「可用容量」之间的差额,正是坏块、预留与元数据共同吃掉的部分。
图 4 · 出厂标记在存储阵列中的位置:主阵列、首块与替换块池

2.3 标记值的约定与判读

标记不是「某一个位等于 1」,而是一段约定:在约定位置、按约定长度、写成约定的非擦除态图案。判读时也不只看一个字节,通常是看约定范围内是否出现了非擦除态的内容。

  • 为什么用「非擦除态」:闪存擦除后整片是擦除态,任何非擦除态的内容都一定是有意写进去的。用这个约定,判读逻辑就不需要知道具体写了什么值,只需要知道「有没有被写过的痕迹」。
  • 为什么写在多个位置:单个字节可能因干扰或读错误被误读。写在块内前几个页的多处,判读时取多数或取「任一命中」,可以显著降低误判。
  • 为什么不能只看一个值:不同厂商、不同工艺代的约定图案不一样。把某个具体值写死在自己的固件里,换一颗器件就会判错。

因此正确的做法是:按所用器件手册给出的位置与判读规则来实现,而不是照抄某个器件的值。这也是本文不列出具体标记值的原因。

判读环节正确做法常见错误后果
位置按器件手册给出的备用区偏移读取照抄别的器件的偏移读到的是用户数据,判读全部失真
长度与范围按约定长度整段判读只读一个字节干扰导致误判或漏判
判读规则按手册定义的「非擦除态」规则写死某个具体图案值换器件即失效
冗余处理多处标记取一致或取多数单点命中即判坏一次读错误就判掉一个好块
异常处理读不出标记时按「未知」处理并复核读不出就当坏块浪费替换块

2.4 首个块为什么特殊

几乎所有 NAND 器件都会对首个块给出额外保证。原因很直接:启动流程往往只能从一个固定位置开始读,如果这个位置是坏的,器件根本起不来。

  • 它是启动链路的入口:很多主控的引导逻辑只认固定偏移,没有能力先扫描全盘再决定从哪里读。
  • 它常常兼作坏块表的落点:整片的坏块结论需要集中存放,而能被启动流程先读到的位置非常有限。
  • 原厂对它有单独的可靠性保证:通常会保证它在一定擦写次数与一定温度范围内可用。

但这份保证是有边界的:它保证的是出厂状态,不是永久状态。首个块同样会被擦写磨损,如果启动流程频繁地往它里面写日志或更新元数据,它也会退化。工程上常见的做法是尽量减少首个块的写入,或者为它的内容准备冗余副本。

首个块的职责为什么选它需要额外注意什么
启动映像入口引导逻辑只能认固定偏移要保证映像本身可跳过坏块
坏块表落点上电最早能读到的位置表本身要有副本与校验
器件标识与参数便于识别器件类型只读为主,避免频繁改写
出厂保证的载体原厂对它有单独可靠性承诺保证限于出厂状态与约定条件

2.5 出厂坏块表的读取时机

读取时机不是越早越好,而是要卡在「任何写操作之前、任何地址分配之前」。一旦固件先做了擦除或编程,之后再读到坏块表就已经晚了——数据可能已经写进坏块。

  • 最早上电阶段:复位后、初始化控制器接口之后、建立可用块视图之前。
  • 文件系统挂载之前:挂载动作本身会产生写,必须先有正确的坏块视图。
  • 任何擦除 / 编程之前:这是对时机的硬要求,没有例外。

读取的代价也要计入启动时间预算:读整张表是顺序读,代价不大;但如果需要全盘扫描来重建表,代价就取决于容量。这就是为什么出厂表要集中存放——它把「上电时的全盘扫描」变成了「一次小范围顺序读」。

时机该做什么不该做什么代价
接口初始化后读取出厂坏块表并建立可用块视图直接初始化文件系统一次小范围顺序读
挂载文件系统前校验表与就地标记是否一致跳过校验直接挂载校验需要额外读,可控
任何写操作前确认目标块不在坏块表内先写再查表无,硬要求
运行期定期增量校验,异常时局部重扫每次上电都全盘重扫全盘重扫耗时随容量增长

2.6 出厂标记的可信边界

最后必须说清出厂标记不保证什么。它是一份很有价值的输入,但把它当成绝对真理会付出代价。

  • 它是某一时刻的结论:筛选门限之下的边缘块会放行,这批块正是现场最先退化的。
  • 它不覆盖使用期产生的坏块:运行时坏块必须由使用方自己判、自己记。
  • 它不保证标记本身永不出错:标记写在闪存里,一样会受干扰与保持力影响,所以需要副本与校验。
  • 它不等于容量保证:可用容量还要扣除预留的替换块池与元数据区。
出厂标记保证的出厂标记不保证的使用方必须补上的
交付时已知坏块已被标出使用期新产生的坏块运行时判坏与标记流程
标记写在约定的可读取位置标记本身永不出错副本、校验与一致性恢复
首块在约定条件下可用首块永久可用减少首块写入 + 冗余副本
坏块比例在原厂门限内具体坏块数恰好等于表中数量上电复核与局部重扫能力

3. 运行时坏块的判定

出厂标记只覆盖了「已知问题」。器件交付之后新产生的坏块,必须由使用方自己判。这一章解决的是四问里的第二问:按什么判据判——哪些事件值得触发判坏流程,哪些只值得重试,以及判错了要付出什么代价。

3.1 哪些事件会触发判坏

运行时会出现各种各样的异常,但绝大多数异常都不应该直接判坏。真正值得进入判坏流程的输入只有几类。

  • 擦除失败:对该块下发擦除命令后,器件返回失败状态,或者擦除完成后检查发现并非擦除态。
  • 编程失败:对该页下发编程命令后返回失败,或者编程后读回的内容与预期不一致。
  • 读纠错量越限:读取时纠错过程消耗的量超过约定门限,说明这个块的余量已经很少。
  • 状态机异常:器件长时间不返回就绪、命令超时、状态位出现异常组合。
  • 上层校验发现不一致:文件系统或应用层的校验和、冗余校验发现数据不可信。

注意最后两类:它们本身不是闪存层的判据,而是上层提供的线索。它们可以触发复核,但不应该直接触发判坏——因为失效的可能不是介质,而是链路、时序或者软件本身。

触发事件来源层次是否直接进入判坏进入判坏前的必经动作备注
擦除失败器件操作层重试后可进入重试擦除、擦除后校验事件型,判据最硬
编程失败器件操作层重试后可进入重试编程、读回比对事件型,但受干扰影响大
读纠错量越限器件操作层复核后可进入换参考重读、多次确认阈值型,门限决定松紧
状态机超时 / 异常接口层不应直接进入复位链路、重新初始化失效可能在链路而非介质
上层校验不一致文件系统 / 应用层不应直接进入定位到具体块后再复核只作为线索使用

3.2 擦除失败的判定

擦除失败是最硬的一类判据。原因是擦除不依赖读判读窗口,也不受纠错能力影响:一个块如果连擦除都完不成,或者擦完之后仍不是擦除态,那它基本没有继续使用的价值。

  • 返回失败状态:器件在擦除过程中或结束后报出失败,这是最直接的判据。
  • 擦除后校验不通过:擦除完成但检查发现存在非擦除态的内容,说明部分单元已经无法被拉回擦除态。
  • 重试仍然失败:单次失败可能是瞬时干扰,重试一次仍然失败才构成可信判据。

擦除失败的处置路径最短:重试一次 → 仍失败 → 判坏 → 标记 → 替换。不需要复杂的纠错统计,因为它本身就是事件型判据。

不过「最硬」不等于「不需要重试」。擦除操作同样可能受到电源波动、时序异常、器件正处于 busy 状态等瞬时因素影响。工程上仍然建议至少重试一次并确认状态,把「器件当时根本没准备好」这类假性失败过滤掉,再进入判坏。

还有一点值得注意:擦除失败发生的位置很重要。如果失败集中在某个固定区域,往往指向工艺或结构性问题;如果分散在全盘且随写入量上升,则更像磨损导致的整体退化。把失败位置记录下来,对后续定位很有帮助。

3.3 编程失败的判定

编程失败同样属于事件型判据,但它比擦除失败更容易被干扰污染,因此处置时要更谨慎一步。

  • 编程过程中报失败:直接反映了器件对该页的编程无法完成。
  • 编程后读回不一致:说明该页没有写到位,属于编程/验证类失败信号;保持力退化则表现为存放一段时间后纠错量上升,两者要分开归因。
  • 同一块内连续多页失败:比单页失败更可信,往往指向块级问题而非页级偶发。

编程失败的处置路径是:重试 → 换页重试(若该块还有可用页)→ 读回校验 → 仍失败则判坏。关键差别在于:编程失败允许「换页」这个中间动作,因为一个块内某一页坏了,不等于整个块都不能用了。

这里也引出了第 5 章要讲的块级替换与页级重映射的取舍:如果只做块级替换,一页坏就废掉整个块,代价偏大;如果做页级重映射,管理复杂度会明显上升。

3.4 读错误:纠错阈值型判坏

读错误是最容易被误用的一类判据。必须反复强调:闪存读出原始 bit 错误是常态,不是故障。真正有意义的是「纠错消耗了多少余量」。

  • 纠错量在低位:正常,无需任何动作。
  • 纠错量接近门限:值得关注,说明这个块的余量在消耗,可作为健康度统计的输入。
  • 纠错量超过门限:进入复核流程,考虑判坏。
  • 纠错无法完成:这是最强的读类判据,相当于事件型。

阈值型判据的关键在于门限怎么定。定得太松,坏块会一直被用到数据真的出错;定得太紧,替换块会被迅速消耗完。工程上通常的做法不是只看一次读数,而是看趋势:同一块的纠错量是否在持续上升。

纠错量所处区间含义处置动作是否计入健康度统计
远低于门限正常工作区间无动作可抽样记录
接近但未超过门限余量在消耗记录趋势,暂不判坏计入,作为趋势输入
超过门限但可纠错余量已经很少换参考重读复核,再决定是否判坏计入,并提升告警级别
无法完成纠错已不可靠直接进入判坏与替换流程计入,并记为一次可靠性事件
最常见的误判:把一次读错误当成判坏依据

读干扰、温度漂移、瞬时电源噪声都可能让某一次读取的纠错量偏高。单次高纠错量不构成判坏依据,它只构成「值得再看一眼」的依据。正确的顺序是:换参考重读 → 多次确认 → 看同块历史趋势 → 才考虑判坏。跳过这些步骤的固件,往往会在器件还很健康的时候就把替换块耗光。

判据的三个层次:越往上越硬,越往下越软事件型判据擦除失败编程失败状态位直接报失败判一次即可,无须统计阈值型判据读纠错量越限接近纠错能力上限需要设定门限门限决定松紧统计型判据同块错误累积趋势重试次数逐步上升磨损计数接近预算多为辅助信号三者的关系:事件型最硬,统计型最软事件型判据来自器件返回状态,可信度最高,处置路径最短:重试一次仍失败即可判坏。阈值型判据来自纠错量这类连续量,可信度取决于门限,必须配重试与复核才安全。统计型判据来自长期趋势,不单独用于判坏,主要用于健康度评估与寿命预测。把统计型当判据会误杀好块;只认事件型又会漏掉渐进退化,两者必须分层使用。
图 5 · 坏块判据的三个层次:事件型、阈值型与统计型

3.5 事件型判坏与阈值型判坏的差别

把判据分成事件型与阈值型,不只是分类游戏,它直接决定了固件的代码结构。两类判据的处理流程差别很大,混在一起写几乎一定会出错。

  • 事件型:输入是离散的(失败 / 成功),处置是「重试固定次数 → 仍失败即判坏」。逻辑简单,路径确定。
  • 阈值型:输入是连续的(纠错量),处置是「多次采样 → 看趋势 → 超过门限才判坏」。逻辑复杂,需要状态记录。

还有一个容易被忽略的差别:事件型判据的误判方向偏「漏判」,阈值型判据的误判方向偏「误判」。事件型只有在器件真的报失败时才动作,所以容易漏掉渐进退化;阈值型只要门限设得稍低就会频繁触发,所以容易误杀好块。

对比维度事件型判据阈值型判据
输入形态离散状态:失败或成功连续量:纠错量、重试次数等
典型来源擦除失败、编程失败读纠错量越限、磨损计数越界
是否需要门限不需要,状态本身即结论需要,门限决定松紧
是否需要历史记录不需要需要,用于看趋势
重试策略固定次数重试换参考重读 + 多次采样
误判倾向偏漏判,渐进退化抓不到偏误判,门限低则误杀好块
典型处置路径重试 → 仍失败 → 判坏采样 → 复核 → 越限 → 判坏
适用阶段出厂筛选与运行时都适用主要在运行时使用
重试阶梯:每一步都比上一步更重,代价也更高① 原样重读一次② 调整读参考电压后重读③ 读出后用更强纠错处理④ 擦除后重写并再次校验⑤ 判坏并写入标记代价递增重试阶梯的设计原则先轻后重:能用一次重读解决的问题,不要动用擦除,擦除本身就是一次磨损。每一步都要留下记录:哪一步解决了问题,是后续调整门限与判断器件健康度的依据。阶梯的顶端是判坏,一旦跨过就不可逆,因此顶端之前至少要留一级复核。
图 6 · 判坏之前的重试阶梯:从原样重读到最终判坏

3.6 判坏之前的重试策略

重试不是「再试一次」这么简单,它是一套逐级加重的阶梯。设计原则很明确:先轻后重,每一步都留记录,顶端之前留一级复核。

  • 原样重读:代价最低,用来排除瞬时噪声。
  • 调整读参考后重读:阈值漂移时,把读参考电压移到更合适的位置往往就能读出来。
  • 用更强的纠错处理:如果器件支持不同强度的纠错,用更强的档位再试一次。
  • 擦除后重写并校验:这一步已经会消耗一次擦写寿命,只有在前面都失败时才用。
  • 判坏并写入标记:阶梯顶端,不可逆。

比阶梯本身更重要的是记录。固件应该记录「哪一步解决了问题」:如果大量错误在第 2 步就被解决,说明阈值漂移是主因,门限可以放宽;如果经常要走到第 4 步,说明器件磨损已经比较严重。

阶梯层级动作代价能解决什么记录什么
第 1 级原样重读一次一次读时间瞬时噪声、偶发干扰重读即恢复的次数
第 2 级调整读参考后重读几次读时间阈值漂移、温度影响需要调参考的块分布
第 3 级更强纠错处理一次读时间 + 算力纠错量偏高但可纠纠错量分布与趋势
第 4 级擦除后重写并校验一次擦写寿命干扰累积、可恢复的软失效走到本级的次数
第 5 级判坏并写入标记消耗一个替换块已确认不可恢复判坏总数与位置分布

3.7 误判的代价

判坏这个动作是不可逆的:一旦把某个块登记为坏块并拿替换块顶上,这个块就基本退出了服务(除非专门设计回收机制)。因此误判的代价必须被认真计算。

  • 判重了(误杀好块):直接代价是消耗一个替换块;间接代价是替换池提前耗尽,器件可用寿命被人为缩短。
  • 判轻了(放过坏块):直接代价是数据可靠性下降;最坏情况是静默数据损坏——数据写进去了、读出来也没报错,但内容已经不对。

两种代价不对称,而且不对称的方向取决于应用场景。消费类场景通常更能接受「少一点容量」,工业与车载场景则更不能接受「数据悄悄错了」。因此判据的松紧不是一个技术参数,而是一个产品决策。

误判方向直接代价间接代价最坏后果更容易发生在
判重(误杀好块)消耗一个替换块替换池提前耗尽,寿命缩短器件在标称寿命前就宣告写满阈值型判据门限过紧
判轻(放过坏块)该块继续承载数据纠错余量被持续消耗静默数据损坏,上层无感知事件型判据缺少复核
标记写错位置表里记录与实际不符后续地址翻译出错数据写到已被判坏的块上标记落点设计不严谨
标记未持久化掉电后结论丢失下次上电重新踩同一个坑反复在同一坏块上失败忽略原子性与掉电场景

4. 运行时标记写到哪、怎么写

判坏只是得到一个结论,真正难的是把这个结论安全地存下来。这一章解决四问里的第三问:写到哪里、怎么写,重点落在原子性与掉电一致性——这是裸 NAND 方案里最容易出问题、也最少被认真设计的一环。

4.1 就地标记与集中登记表

运行时标记同样有两类落点,而且强烈建议两者并用。

  • 就地标记:在该块自己的备用区写入约定图案。优点是就地可得,读这个块时就顺带知道它的状态;缺点是分散在全盘,要拿到全盘结论就得全盘扫描。
  • 集中登记表:在一处集中记录所有坏块。优点是上电一次读出全部结论;缺点是它自己也是一份需要保护的数据,写入时同样面临掉电风险。

两者并用的价值在于互为备份:登记表丢失可以靠就地标记重建,就地标记丢失可以靠登记表恢复。只有一份的设计,在掉电场景下几乎一定会出问题。

方案上电代价掉电后恢复能力占用空间适用建议
只做就地标记需要全盘扫描才能重建结论强,标记本身分散且就地极小,随块分布小容量器件可接受
只做集中登记表一次顺序读拿到全盘结论弱,表本身损坏即全盘未知随坏块数增长不推荐单独使用
就地标记 + 登记表先读表,异常时回查就地标记强,两份可互相校验与重建两者之和推荐做法
登记表 + 多份副本读主表,失败读副本较强,取决于副本份数随份数线性增长对启动时间敏感时适用

4.2 标记的原子性:掉电中断会怎样

「原子性」在这里的含义很朴素:一次标记操作,要么完全生效,要么完全不生效,不能停在中间状态。而现实是:写标记这件事本身至少包含两个独立的写动作(就地标记 + 登记表更新),掉电可以在任意时刻发生。

  • 掉电在写就地标记之前:两份都没有,块仍是好块,下次还会被用到,会再失败一次。代价最小。
  • 掉电在就地标记之后、登记表之前:就地标记已生效,登记表没更新。两份结论不一致,这是最需要处理的情形。
  • 掉电在登记表之后:两份都生效,状态一致,代价只是损失一次写。

应对思路不是「让写操作变原子」(做不到),而是让不一致状态可被检测到、可被收敛。具体做法是:给标记写一份可校验的结构(顺序号或校验字段),上电时比较两份的顺序号,以较新的一份为准,并把较旧的一份补齐。

掉电发生的时刻就地标记状态登记表状态上电后的处理代价
写就地标记之前未写未更新当作未判坏,下次重新走判坏流程一次重复判坏
就地标记之后、表之前已写未更新以就地标记为准,回补登记表一次回补写
表更新之后已写已更新状态一致,无需处理无额外代价
正在写就地标记可能部分写入未更新校验失败则视为未写,重新写一次一次重写
标记写入不是原子操作:掉电点决定了上电后要做什么① 写就地标记块内备用区写入非擦除态图案② 更新登记表集中表内追加该块记录③ 刷新内存视图可用块视图同步更新④ 掉电发生在 ② 之前就地标记已写入集中表还没更新两份结论不一致⑤ 上电后的一致性恢复以就地标记为准回扫并补齐登记表内存视图重新构建设计要点:做不到原子,就做到可检测、可收敛给标记加顺序号或校验字段,上电时比较两份结论的新旧,以较新的一份为准。就地标记要写在块内前几个页的多处,避免单点读错误造成误判。登记表更新采用「先写新、后失效旧」的顺序,任何时刻至少有一份可用。内存视图永远视为缓存,掉电即失效,上电必须重新从持久层重建。
图 7 · 运行时标记的原子写入与掉电中断后的收敛路径

4.3 标记副本与一致性恢复

一致性恢复的目标不是「不出错」,而是「出错之后能收敛到一个确定的状态」。常用的手段有三个。

  • 顺序号:每份标记带一个单调递增的序号,比较两份的序号就知道谁更新。
  • 校验字段:让半写状态可被检出,避免把写了一半的内容当成有效结论。
  • 先写新、后失效旧:更新登记表时先把新版本写好,再把旧版本标记为失效,保证任何时刻至少有一份完整可用。

恢复流程应当固化成一个幂等的函数:上电时无条件调用,无论上次掉电发生在哪一步,调用之后系统一定处于一致状态。把恢复逻辑写成「针对某种特定掉电场景的处理」,一旦出现没预料到的场景就会卡死。

4.4 什么时候需要全盘重扫

全盘重扫是最彻底的恢复手段,也是代价最高的。它的触发条件必须明确,否则要么频繁拖慢启动,要么该扫的时候没扫。

  • 登记表所有副本都校验失败:这是最强的触发条件,说明集中结论已经不可信。
  • 就地标记与登记表冲突且无法判定新旧:两份结论矛盾又分不出先后,只能回去挨个看。
  • 首次使用一颗新器件且没有可信表:某些情况下需要建立基线视图。
  • 怀疑介质整体退化:例如长期高温存放后重新上电。

不建议把全盘重扫作为常规启动动作。它的耗时随容量增长,在大容量器件上会明显拖慢启动。合理的设计是:常规启动只读表,把全盘重扫留给异常分支,并且允许它在后台进行、先用表里的视图把系统拉起来。

触发条件是否必须阻塞启动代价建议做法
登记表所有副本校验失败是,否则没有可用视图一次全盘读阻塞启动,扫完再挂载
就地标记与表冲突且无法判定是一次全盘读以就地标记为准重建表
首次使用新器件视情况一次全盘读可在后台完成,先用表启动
长期高温存放后重新上电否一次全盘读后台扫描,前台照常用表
常规上电否极小只读表与副本,不做全盘扫描

4.5 标记信息的存放位置约束

标记落点不是随便选的,它受三条硬约束限制。

  • 必须在任何擦除之前可读:如果标记所在的区域可能在正常操作中被擦掉,这份标记就没有意义。
  • 必须能被判读者在最早的上电阶段读到:如果读标记需要先初始化文件系统,那它在启动场景里就不可用。
  • 不能放在它所管理的介质之外的不可靠位置:把坏块表放在另一颗同样会坏的器件上,只是把风险搬了个家。

这三条约束合起来,解释了为什么块内备用区 + 保留块会成为主流组合:备用区满足「就地可得」,保留块满足「最早可读」,两者都在同一颗器件内部,不需要外部依赖。

一个值得记住的判断

如果一份坏块标记需要依赖另一份数据的正确性才能被读到,那它就是不可靠的。检查自己的设计时可以问一句:「如果文件系统损坏、如果元数据区坏了,这份标记还能被读出来吗?」答案如果是否定的,这份设计在启动场景里就是有风险的。

相关报告 · 交叉引用 1 器件全部展开收起 ▾
点开类目即可展开:具体文档 / 章节(点章直接跳转到该章)
eMMC
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查
其他提及器件(共 1)
SD NAND
电路设计指南
软件设计规范
Linux 驱动开发
量产问题排查