Nand: OOB BBT ECC PEB LEB

本文深入探讨了NAND Flash存储器的工作原理,包括块页式存储管理、存储操作特点、坏块表(BBT)管理、ECC校验机制以及PEB和LEB的概念。详细解析了NAND Flash的存储布局、存储操作流程,以及如何通过ECC校验和坏块表来确保数据的完整性和可靠性。

OBB:

例如Samsung K9F1208U0B,数据存储容量为64MB,采用块页式存储管理。8个I/O 引脚充当数据、地址、命令的复用端口。
芯片内部存储布局及存储操作特点: 一片Nand flash为一个设备(device), 其数据存储分层为:

    1 (Device) = 4096 (Blocks)
    1 (Block) - = 32   (Pages/Rows) 页与行是相同的意思,叫法不一样
    1 (Page)   = 528 (Bytes) = 数据块大小(512Bytes) + OOB 块大小(16Bytes)


     在每一页中,最后16个字节(又称OOB)用于Nand Flash命令执行完后设置状态用,剩余512个字节又分为前半部分和后半部分。可以通过Nand Flash命令00h/01h/50h分别对前半部、后半部、OOB进行定位通过
Nand Flash内置的指针指向各自的首地址。

    存储操作特点:
    1. 擦除操作的最小单位是块。
    2. Nand Flash芯片每一位(bit)只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前要一定将相应块擦除(擦除即是将相应块得位全部变为1).
    3. OOB部分的第六字节(即517字节)标志是否是坏块,如果不是坏块该值为FF,否则为坏块。
    4. 除OOB第六字节外,通常至少把OOB的前3个字节存放Nand Flash硬件ECC码。



BBT:

Bad Block Table,即坏块表。各家对nand的坏块管理方法都有差异。比如专门用nand做存储的,会把bbt放到block0,因为第0块一定是好的块。但是如果nand本身被用来boot,那么第0块就要存放程序,不能放bbt了。

有的把bbt放到最后一块,当然,这一块不能为坏块。

有的bbt中用2个bits表示1个block的状态,所以1个字节可以表示4个blocks。

bbt的大小跟nand大小有关,nand越大,需要的bbt也就越大。

所以具体代码具体分析。


ECC:

NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出 错。一般使用一种比较专用的校验——ECC。ECC能纠正单比特错误和检测双比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的 错误不保证能检测。

ECC一般每256字节原始数据生成3字节ECC校验数据,这三字节共24比特分成两部分:6比特的列校验和16比特的行校验,多余的两个比特置1.

当往NAND Flash的page中写入数据的时候,每256字节我们生成一个ECC校验和,称之为原ECC校验和,保存到PAGE的OOB(out-of-band)数据区中。其位置就是eccpos[]。

校验的时候,根据上述ECC生成原理不难推断:将从OOB区中读出的原ECC校验和新ECC校验和按位异或,若结果为0,则表示不存在错(或是出现了 ECC无法检测的错误);若3个字节异或结果中存在11个比特位为1,表示存在一个比特错误,且可纠正;若3个字节异或结果中只存在1个比特位为1,表示 OOB区出错;其他情况均表示出现了无法纠正的错误。


PEB:

physical eraseblock (size)


LEB:

logical eraseblock (size)







### NAND FlashECCOOB 的概念及实现 #### 错误校正码 (ECC) 错误校正码用于检测并纠正数据读取过程中可能出现的位翻转错误。NAND Flash 存储介质容易受到物理损坏的影响,因此需要强大的纠错机制来确保数据可靠性。通常情况下,每512字节的数据会附加一定数量的ECC比特,在写入时计算这些额外的信息,并在读回时用来验证和修正可能存在的单一位错或其他少量错误[^2]。 为了适应不同应用场景的需求以及提高存储效率,现代 NAND 芯片支持多种 ECC 强度设置。随着技术进步,能够处理更多随机错误的新一代算法也被引入到 NAND 控制器中,比如 BCH 编码或者 LDPC(低密度奇偶校验)编码方案。 ```python # Python伪代码展示如何应用简单的汉明码作为ECC的一个例子 def calculate_hamming_code(data_bits): r = 0 while ((len(data_bits) + r + 1) >= pow(2, r)): r += 1 hamming_list = [None]*(len(data_bits)+r) j = 0 k = 1 for i in range(1,len(hamming_list)+1): if(i == pow(2,k-1)): hamming_list[i-1]= 'P'+str(k) k+=1 else: hamming_list[i-1]= data_bits[j] j+=1 parity_positions=[pow(2,x)-1 for x in range(r)] for p in parity_positions: positions_to_check=[i for i in range(len(hamming_list)) if((i+1)&p==p)] count=0 for pos in positions_to_check: if isinstance(hamming_list[pos], str) and not('P' in hamming_list[pos]): count=count^(ord(hamming_list[pos])-ord('0')) hamming_list[p]='P'+str(count%2) return ''.join([bit if type(bit)==str else chr(ord('0')+int(bit)) for bit in hamming_list]) ``` #### 带外区域 (OOB Area) 带外区域是指位于每个页面实际用户可访问地址空间之外的一小部分保留区。这部分主要用于保存元数据信息,如坏块标记、逻辑地址映射表项以及其他控制结构等重要参数。对于某些文件系统而言,OOB 还可以承载额外的功能特性,例如 JFFS2 文件系统的 Wear Leveling 数据记录就依赖于该区域完成。 当执行擦除操作之前,如果发现某个区块存在过多不可修复的错误,则会在相应的 OOB 区域中标记此区块为“坏”,从而防止后续对该位置继续进行编程或读取尝试。这种做法有助于维持整个设备长期稳定运行的同时减少因硬件缺陷带来的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值