对nand bbt的理解
blob输出如下:
NAND flash(Manu=0x2c Device=0xba)
Slot 0 Found
Block #14 is relocated to #2047
Block #175 is relocated to #2046
Block #192 is relocated to #2045
Block #705 is relocated to #2044
Block #706 is relocated to #2043
Block #727 is relocated to #2042
Block #829 is relocated to #2041
Block #1028 is relocated to #2040
Block #1029 is relocated to #2039
Block #1030 is relocated to #2038
Block #1032 is relocated to #2037
Block #1083 is relocated to #2036
Block #1303 is relocated to #2035
Block #1626 is relocated to #2034
Block #1795 is relocated to #2033
Block #1799 is relocated to #2032
Block #2004 is relocated to #2031
Found Main Bad block table at address 0x0fd60000, version 0x01
Found Mirror Bad block table at address 0x0fd20000, version 0x01
0x0FD60000 = /1024*128 = 2027块
256M = /1024*128 = 2048块
在blob的nandwrite.c中有如下定义:
#if defined(TAVOR_EVB2)
#define NAND_RELOC_MAX 20
#else
#define NAND_RELOC_MAX 127
#endif
block的shift=17
page 的shift=11
所以1个block含有1<<(17-11)=64个page
monahans_nand.chipsize = (pFlashInfo->numBlocks - NAND_RELOC_MAX) << monahans_nand.phys_erase_shift;
chipsize_blocks = (2048-20)=2028块,索引范围:0~2027
所以可以看出第2028~2048共20个block用于relocate,不作为chipsize范围,
在static int read_rel_table(struct nand_info *info);函数中,
...
page = 1 << (info->phys_erase_shift - info->page_shift);
...
maxslot = 1 << (info->phys_erase_shift - info->page_shift);
page = maxslot - MAX_BBT_SLOTS;
//在nandwrite.c中的定义如下:#define MAX_BBT_SLOTS 24
...
block 0
nand flash的第1个block,即:0索引号块,的后24个page用于slot,即:39~59索引号块,首先填充59号,之后依次向下,直到39块被使用,那么将
重新擦出block0,进入下一个循环.
nand flash的chipsize表示的最后2个blocks用来存放bbt内容,这里对应的绝对地址为0x0fd60000,即:2027索引号块,对于2048个字节每扇区,那么可以管理2048*4=8k个block,所以一共可以管理8k*128k=1G的nand flash空间,
1个block大小0x20000字节
256M一共2048个blocks,一共需要2048/4=512字节的bbt空间来管理
read_rel_table函数将使info->table存放slot中的数据,该table的结构定义如下:
struct nand_rel_table{
u16 header;
u16 total;
struct {
u16 from;
u16 to;
} rel[NAND_RELOC_MAX];
};
#define NAND_RELOC_HEADER 0x0000524e //= 'N' + ('R' * 256)
如果table.header == NAND_RELOC_HEADER的话,说明该slot存放了数据,直接返回该slot的内容作为block重定位的基础
td->maxblocks对应&monahans_bbt_main
static struct nand_bbt_descr monahans_bbt_main = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_VERSION,
.veroffs = 6,
.maxblocks = 2,
.len = 4,
.offs = 2,
.pattern = scan_main_bbt_pattern,
};
所以使用了2个blocks来存放td
这也就是0x0fd20000=/128k = 2025 = 2027 - 2 的原因,故
td使用2026~2027块,td->pages指向2027
md使用2024~2025块,md->pages指向2025
在static int search_bbt(struct nand_info *info, u8 *buf,struct nand_bbt_descr *td, int bbt_blocks)函数中,
将读取2027中的bbt内容,装入buf缓冲区,然后使用
static inline void set_bbt(u32 block, u8 val, struct nand_info *info)函数填充
info->bbt表,bbt中用2个bits表示1个block的状态,所以1个字节可以表示4个blocks,
nand中0x03表示该block是好的,但在info->bbt中0x03表示坏,0x00表示好,0x01和0x02分别对应坏块是由谁标记的
所以256M nand的每一个block在bbt中都有对应的项,最后1个block的状态由td->bbt[512]中的2bits数据指示.
如果bbt被毁坏或者没有创建,blob将调用static int create_bbt(struct nand_info *info, u8 * buf);函数
创建一个新的bbt,感觉对于坏块的检测,blob的实现很简单,仅仅检测每个block的前2个page的0~1字节是否为0xff,
所以感觉nand的擦出操作是倒着擦出,先擦最高page,最后擦出第0 page(gliethttp_20080312)
|