4. 坏块表管理:BBT结构设计、RAM维护与NAND存储更新

坏块表,简称BBT。这玩意儿是NAND Flash管理的核心之一。说白了,它就是一张“黑名单”,记录着哪些块是坏的、不能用的。

我刚开始做NAND驱动时,觉得BBT不就是个标记嘛,有啥难的?后来踩了坑才明白——BBT的设计好坏,直接决定了系统的稳定性和寿命。今天咱们就把它掰开揉碎了讲清楚。

4.1 BBT结构设计——这张表长什么样?

BBT的结构,不同厂家有不同玩法。但核心思路是一致的:用最少的空间,管理最多的坏块。

我个人习惯把BBT设计成两级结构:

  • 一级表(主表):记录每个块的坏块状态。一个bit对应一个块,0表示好块,1表示坏块。
  • 二级表(扩展表):当主表所在的块也坏了,就用扩展表来记录。

举个例子,一颗8GB的NAND,假设有4096个块。用bitmap方式,只需要4096个bit,也就是512字节。你看,空间效率很高。

BBT条目格式(我常用的):

// 每个块对应1个bit
// 0x00 = 好块
// 0x01 = 坏块

// 假设有4096个块,BBT大小为512字节
uint8_t bbt[512];  // 512字节 = 4096 bit

这里要注意:BBT本身也要占用一个块。这个块必须是好块,否则BBT存哪儿?

我曾经踩过的坑: 有一次设计BBT时,没考虑主表块损坏的情况。结果主表块坏了,整个系统找不到坏块信息,直接崩溃。后来我加上了二级表机制,才彻底解决这个问题。

4.2 RAM中BBT的维护——快,但要小心

BBT在NAND里存着,但每次读写都去NAND里查,速度太慢了。所以,我们会在RAM里维护一份BBT的副本。

RAM中的BBT,说白了就是NAND中BBT的“缓存”。系统启动时,从NAND加载到RAM;运行时,在RAM里更新;需要时,再写回NAND。

我建议用以下方式维护RAM中的BBT:

  1. 启动时加载:从NAND的指定位置读取BBT,存入RAM。
  2. 运行时更新:每次发现新坏块,立即更新RAM中的BBT。
  3. 定期回写:将RAM中的BBT写回NAND,防止掉电丢失。

小技巧: 我习惯在RAM中维护一个“脏标记”。只要BBT有更新,就把脏标记置1。回写时,只回写脏标记为1的BBT。这样可以减少NAND的写入次数,延长寿命。

你想想看,如果每次发现坏块都立刻写回NAND,那NAND的寿命会急剧下降。所以,延迟回写是个好策略。

4.3 NAND中BBT的存储与更新——怎么存?怎么改?

NAND里的BBT,通常存储在最后一个块或者前几个块。不同厂家有不同约定,但海力士的习惯是存在最后一个块。

BBT在NAND中的存储格式,我一般这样设计:

偏移 内容 大小
0x00 BBT标识(固定为0x424254) 4字节
0x04 版本号 4字节
0x08 块总数 4字节
0x0C 坏块位图 可变
末尾 CRC校验 4字节

更新BBT时,流程是这样的:

  1. 在RAM中标记新坏块。
  2. 将RAM中的BBT数据准备好。
  3. 擦除NAND中存放BBT的块。
  4. 将新BBT写入该块。
  5. 验证写入是否正确。

注意: 擦除操作有风险。如果擦除过程中掉电,BBT就丢了。我建议在擦除前,先把BBT备份到另一个块。等擦除完成、写入成功后,再释放备份块。

嗯,这里还要提一点:BBT的更新频率。我个人建议,每次系统关机或休眠前,强制回写一次BBT。平时运行时,可以每发现10个新坏块,或者每过1小时,回写一次。具体频率,得看你的系统对数据安全的要求。

4.4 核心逻辑流程图

下面这张图,是我根据多年经验总结的BBT管理核心流程。你看一眼,基本就明白整个体系了。

BBT管理核心流程 系统启动 从NAND加载BBT到RAM 运行时检测到新坏块 更新RAM中的BBT(置脏标记) 需要回写? 回写BBT到NAND (擦除→写入→验证) 继续检测 回写完成 启动 加载 检测 更新RAM 判断 回写NAND

这张图把BBT的整个生命周期都串起来了。从启动加载,到运行时更新,再到条件回写,每一步都环环相扣。

4.5 实战中的几个要点

最后,分享几个我在项目中积累的经验:

  • BBT的备份:至少保留两份BBT副本。一份在主块,一份在备用块。万一主块坏了,还有救。
  • 版本控制:每次更新BBT,版本号加1。这样能判断哪份BBT是最新的。
  • CRC校验:BBT数据必须带CRC。NAND有比特翻转的风险,CRC能帮你发现数据是否损坏。
  • 原子操作:更新BBT时,尽量保证操作的原子性。如果做不到,至少要有回滚机制。

我的个人习惯: 每次设计BBT时,我都会预留一些扩展字段。比如预留16字节的厂商自定义区域。这样后续要加功能,不用改整体结构。你想想看,产品迭代时,这个预留字段能省多少事。

好了,BBT这块的内容就讲到这里。记住一句话:BBT是NAND的生命线,设计时多花心思,运行时少出问题


公众号:蓝海资料掘金营,微信deep3321