uboot中nandflash bbt创建过程

arm/lib/board.c

board_init_r()

{

……

nand_init();

env_relocate();

……

}

 

common\env_common.c

void env_relocate(void)

{

……

env_relocate_spec();

……

}

 

common\env_nand.c

void env_relocate_spec(void)

{

readenv(CONFIG_ENV_OFFSET, (u_char *)buf);

}

 

drivers/mtd/nand/nand_base.c

static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)

{

……

if (nand_block_isbad(&nand_info[0], offset))

{}

……

}

 

drivers/mtd/nand/nand_base.c

static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)

{

return nand_block_checkbad(mtd, offs, 1, 0);

}

 

drivers/mtd/nand/nand_base.c

static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,       int allowbbt)

{

chip->scan_bbt(mtd);

 

/* Return info from the table */

return nand_isbad_bbt(mtd, ofs, allowbbt);

}

 

drivers/mtd/nand/nand_bbt.c

int nand_default_bbt(struct mtd_info *mtd)

{

if (!this->badblock_pattern)

nand_create_default_bbt_descr(this);

 

return nand_scan_bbt(mtd, this->badblock_pattern);

 

}

 

drivers/mtd/nand/nand_bbt.c

int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)

{

//bbt表分配内存

nand_memory_bbt(mtd, bd)

}

 

drivers/mtd/nand/nand_bbt.c

static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)

{

struct nand_chip *this = mtd->priv;

 

bd->options &= ~NAND_BBT_SCANEMPTY;

return create_bbt(mtd, this->buffers->databuf, bd, -1);

}

 

比如对于一个 Samsuny KF2G08 256Mnand,共有2048Block,其中每个块的共有64页,一个页的大小为2048+64Byte,即一个页中主存储区的大小2048Byte, spare 区域的大小为64Byte,其中的OOB信息就存储在spare区域。对于 large page型的nand,即一个页的主存储区大于512Bytenand,一个块是否为好坏,用这个块的第一个page和第二个pagespare区的第一个字节来标记,若这两个块中spare区中的第一个字节值都为0xFF则该坏为好坏,否则为坏块,nand_chip->bbt数组的大小,本例中为512Byte。大小的计算方法为:512 * 8 / 2 =  2048。即用两个bit表示一个块是好的还是坏的。

create_bbt中有一个循环,通过调用scan_block_fast()对每一个块是否完好的信息进行读取,并进行判断,若为坏块,填充对应的bbt数组。scan_block_fast()最终会调用nand_read_oob_std()进行真正OOB信息读取。在读取到信息之后,nand_scan_fast中调用 check_short_pattern进行判断读取到的OOB信息,该信息中的第1个字节反映了是否为坏块。若为坏块,则返回非零到create_bbt函数中,在create_bbt中往nand_chip->bbt 这个数组中填充该块是否为坏块。一个坏块标记占用2bituboot中用两个bit "11"来标志对应的坏为坏块。两个bit "00"标志对应的块为好坏。

 

最后读取完整个nandOOB信息后,通过nand_isbad_bbt用来判断指定的块是否为坏坏。

 

spare区中存储的是OOB信息,一个block中的第一个page和第二个pagespare区中的第一个字节用来保存块是否完好的信息外,spare区的其它内容为ECC校验信息,用来表示主存储区的数据的校验值,每512Byte会生成一个校验值,一个校验值为3个Byte,可以用此来判断讲到的数据是否反转。

 

nand_read_buf用来一个一个读取字节内容。

 

 

create_bbt 0 len 2, chip -1

create_bbt 1 scanlen 0, readlen 1

create_bbt 2 from 0x00000000, numblocks 0x00001000

create_bbt 4 from 0x00000000, buf[0] 0, len 0x00000002

 scan_block_fast j 0, offs 0x00000000, len 2 , ops.ooblen 64

        nand_read_oob 0 from 0x00000000

        nand_do_read_oob 0 chip->oob_poi[0] 0, page 0x00000000, sndcmd 1, len 64, readlen 64

        nand_command_lp column 0x00000800, ctrl 0x00000005

        nand_command_lp page_addr 0x00000000, ctrl 0x00000005

        nand_read_oob_std 0 NAND_CMD_READOOB 0x00000050, page 0, sndcmd 1

        nand_read_buf buf:f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

        nand_read_oob_std 1 chip->oob_poi[0] f0, mtd->oobsize 0x00000040

        nand_do_read_oob 1 chip->oob_poi[0] f0, page 0x00000000, sndcmd 0, len 64

        nand_do_read_oob 2 buf[0] 0, sndcmd 0

        nand_read_oob 1 from 0x00000000, ret 0

        check_short_pattern 0 td->len 1, p[td->offs + i] f0, td->pattern[i] ff

create_bbt 5 from 0x00000000, buf[0] f0, len 0x00000002, ret 1

        create_bbt 6, this->bbt[i >> 3] 0

****####create_bbt 7, i 0x00000000, i>>1 0x00000000, bbt[i>>3] 3, Bad eraseblock 0 at 0x000000000000, ret 1, mtd->ecc_stats.badblocks 1

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值