OOB
目前比较常见NAND Flash每一页大小为(2048+64)字节(还有其他格式的NANDFlash,比如每页大小为(256+8)、(512+16)、(2048+128)等),其中的2048字节就是一般存储数据的区域,64字节称为OOB(Out OfBand)区。通常在OOB区存放坏块标记、ECC较验码、文件系统信息(yaffs)等。
而cramfs、jffs2文件系统映像文件中并没有OOB区的内容,如果将它们烧入NORFlash中,则是简单的“平铺”关系;如果将它们烧入NAND Flash中,则NANDFlash的驱动程序首先根据OOB的标记略过坏块,然后将一页数据(2048字节)写入后,还会计算这2048字节的ECC较验码,最后将它写入OOB区,如此循环。
ECC
ECC的全称是Error Checking and Correction,是一种用于Nand的差错检测和修正算法。如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。ECC能纠正1个比特错误和检测2个比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。
校验码生成算法:ECC校验每次对256字节的数据进行操作,包含列校验和行校验。对每个待校验的Bit位求异或,若结果为0,则表明含有偶数个1;若结果为1,则表明含有奇数个1。列校验规则如表1所示。256字节数据形成256行、8列的矩阵,矩阵每个元素表示一个Bit位。
NandFlash的ECC校验算法,只能纠正一个bit的错误。实现过程就是在存入数据时计算ECC校验,在读出数据时再次计算ECC校验,如果两次计算结果不同,则数据在存储过程中肯定发生了变化,通常是存储某个bit的电气元件电平发生了翻转。在实际过程中,我们会通过两次计算结果对比来找到是哪一个bit发生了变化,然后更正它即可。所以重点在于怎么找到这个发生了变化的bit。
其实ECC校验我觉得主要用了两个点:异或和二分法。
异或的结果就是相同为0,不同为1,理解这个概念很重要。
然后就是二分法,逐步缩小范围。
牢记以上两点即可完全理解ECC校验方式。
我们先举一个简单的例子:现在我向NandFlash里存了8个字节的数据,它们全部为0。如下图:
![](https://img-blog.csdnimg.cn/img_convert/3d66db295dde48425a5de34115e41520.png)
后我把数据读出来,发现其中一个bit发生了翻转。如下图:
![](https://img-blog.csdnimg.cn/img_convert/59c8257c5a297118d92864c5a361a0a7.png)
我们读出来的时候并不知道存入的数据到底是多少,那ECC又是如何通过两次计算来确定是哪个bit发生了变化?
实际操作如下:
在存入数据时,计算8个字节bit0-bit3所有位的异或结果得到一个位(32个位异或的结果),再计算bit4-bit7所有位的异或结果又得到一个位(同样32个位)
![](https://img-blog.csdnimg.cn/img_convert/b25194cb666206191d594788e9c4edb5.png)
在读取的时候我再次计算这个两个位:
![](https://img-blog.csdnimg.cn/img_convert/23330a22df4739dab94f9f72c5fca13b.png)
这样,通过两次计算结果中两个位比较,可以确定是bit0-bit3中出现了错误,还是bit4-bit7中出现了错误。这是第一次二分,用两个位筛选掉了一半的位。同理,我们可以在bit0-bit3中再次二分,可以确定是bit0-bit1中出现了错误还是bit2-bit3中出现了错误。也就是我在写入和读出时再加4个bit。如下图:
写入:
![](https://img-blog.csdnimg.cn/img_convert/b558b98401238d33eec1fad5e1c6f79d.png)
读出:
![](https://img-blog.csdnimg.cn/img_convert/4564cca0cf058d261e055226021fafcf.png)
此时,我们把错误位定位到了bit2-bit3中间。再继续,我们可以再加8个位去再次二分,最后得到错误的位就在bit2这个位。这么乍一听好像没有问题,其实不然。我们在实际写入和读取时,并不知道到底是哪一位是错误的,所以我们每一列bit都要计算,而并不是先计算bit0-bit3和bit4-bit7,在判断是bit0-bit3存在错误后再计算bit0-bit1和bit2-bit3,而是我们要计算出2+4+8 = 14个部分bit的异或结果:
![](https://img-blog.csdnimg.cn/img_convert/444d7791e132050943f909125f2937bb.png)
从上面的检测原理来看,ECC只能检测每个块中的1个bit,多于一个bit会出现负负得正的情况,也没办法修正。