真惭愧,看了很长时间终于对nandflash建立坏块表有所了解
我们来看一下下面这个程序:
for (i = startblock; i < numblocks;) {
nand_read_raw (mtd, buf, from, readlen, ooblen);
for (j = 0; j < len; j++) {
if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
break;
}
}
i += 2;
from += (1 << this->bbt_erase_shift);
}
这个就是建立坏块表的程序,这边的this->bbt[i >> 3] |= 0x03 << (i & 0x6);看了很长时间,
在网上找了一下就如下意思:/* 注意:这里i=实际值*2。由于一个block的状态用2bit来表示,那么一个字节可以存放4个block的状态。这里i>>3刚好是实际block/4,4个block的状态刚好存放在this->bbt所指向的一个字节里面。
从这句话里我终于知道,4968,4970,4972,4974为什么除以8以后都是621了。
下面的这个函数是判断这块是否是坏块的
int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
{
struct nand_chip *this = mtd->priv;
int block;
uint8_t res;
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
/* Get block number * 2 */
block = (int) (offs >> (this->bbt_erase_shift - 1));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, res, block >> 1);
switch ((int)res) {
case 0x00: return 0;
case 0x01: return 1;
case 0x02: return allowbbt ? 0 : 1;
}
return 1;
}
最重要的一句是res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03,上一个程序的变量i和这程序的block的类型是一样的。
我们来分析一下这两条语句有什么不同:
this->bbt[i >> 3] |= 0x03 << (i & 0x6);其实可以简化成:this->bbt[i >> 3]=3*(2^(i & 0x6));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;这个也可以简化成: res=( this->bbt[block >> 3]/(2^(block & 0x6));
如果i和block是一样的,那么res算出来的应该就是0x3了,前提是i和block是一样的,虽然上面提到4个block的状态刚好存放在this->bbt所指向的一个字节里面,但block不和i一样的话,res也就不会为0x3的。
比如:如果block=4968的时候,res=(this->bbt[621] >> (4968 & 0x6)) & 0x3
=(0xc0 >> 0) &0x3=0
当bloc=4970和4972的时候,res都为0,只有当block=4974的时候,block=0x3;
这样就可以判断是否是坏块了。
文章评论(0条评论)
登录后参与讨论