开发?p>
澹?jz2440_v3
/**
* create_bbt - [GENERIC] Create a bad block table by scanning the device
* @mtd: MTD device structure
* @buf: temporary buffer
* @bd: descriptor for the good/bad block search pattern
* @chip: create the table for a specific chip, -1 read all chips.
* Applies only if NAND_BBT_PERCHIP option is set
*
* Create a bad block table by scanning the device
* for the given good/bad block identify pattern
*/
static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
{
struct nand_chip *this = mtd->priv;
int i, j, numblocks, len, scanlen;
int startblock;
loff_t from;
size_t readlen, ooblen;
if (bd->options & NAND_BBT_SCANALLPAGES)
len = 1 << (this->bbt_erase_shift - this->page_shift);
else {
if (bd->options & NAND_BBT_SCAN2NDPAGE)
len = 2;
else
len = 1;
}
// len = 1
scanlen = mtd->oobblock + mtd->oobsize; // 2048 Bytes + 64 Bytes
readlen = len * mtd->oobblock; // 2048
ooblen = len * mtd->oobsize; // 64
if (chip == -1) {
/* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
* makes shifting and masking less painful
* 请注意,这里的 numblocks 是2*(真正的numblocks),请参阅下面的i+=2,
* 因为它可以减少移位和掩蔽的痛苦
*/
numblocks = mtd->size >> (this->bbt_erase_shift - 1); // 2048*2 = 4096 blocks
startblock = 0;
from = 0;
} else {
if (chip >= this->numchips) {
printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)
",
chip + 1, this->numchips);
return;
}
numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
startblock = chip * numblocks;
numblocks += startblock;
from = startblock << (this->bbt_erase_shift - 1);
}
for (i = startblock; i < numblocks;) {
// buf 为 1 block 的大小: (2048 Byte + 64 Byte) * 64 page
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定义在:
* nand_scan_bbt 中设置的 默认值: 0x00 (注:在本文中)
*
* 含义:
* 四个block的坏块信息存在一个this->bbt[]数组里,
* 二进制的11表示其中一个是坏块,
* 二进制的00表示其中一个是好块。
*
* 实例:
* this->bbt[0]=03;
* 表示有一个坏块,分别是block 0;
* this->bbt[3]=30;
* 表示有一个坏块,分别是block 14;
* this->bbt[256]=3f;
* 表示有三个坏块,分别是block 1024,1025,1026
*
* 注意(Note That):
*
* 芯片为小端模式,存储排列顺序为:
* 00 00 00 00
* 3 2 1 0 ---> block index
* .
* .
* .
* 00 00 00 00
* 1027 1026 1025 1024 ---> block index
*
*/
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
/**
* 如果不乘2,表达式该为:
* this->btt[i>>2] |= 0x3 << (i & 0x3)*2;
* 硬件操作为:取最后两位,再向右移动一位
* 优化后:先移位然后再取后3位
*/
break;
}
}
i += 2;
from += (1 << this->bbt_erase_shift);
}
}