加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

u-boot-2014.10移植第22天----添加nand flash命令支持(四)

发布时间:2020-12-15 17:26:26 所属栏目:百科 来源:网络整理
导读:解决问题: nand0: MTD Erase failure: -5 drivers/mtd/nand/nand_bbt.c文件中初始化bbt /* * Allocate memory (2bit per block) and clear the memory bad block * table. */ this-bbt = kzalloc(len,GFP_KERNEL); if (!this-bbt) return -ENOMEM; 每个bloc

解决问题:

nand0: MTD Erase failure: -5  

drivers/mtd/nand/nand_bbt.c文件中初始化bbt

/*
     * Allocate memory (2bit per block) and clear the memory bad block
     * table.
     */
    this->bbt = kzalloc(len,GFP_KERNEL);
    if (!this->bbt)
        return -ENOMEM;

每个block用2个比特表示是否为坏块。

nand_scan_bbt

------>nand_memory_bbt

----------->create_bbt

---------------->scan_block_fast

下面的两个函数用来查看和标记上面说的每个block的2比特位。初步分析坏块时2比特位置为11。

static inline uint8_t bbt_get_entry(struct nand_chip *chip,int block)
{
    uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT];
    entry >>= (block & BBT_ENTRY_MASK) * 2;
    return entry & BBT_ENTRY_MASK;
}

static inline void bbt_mark_entry(struct nand_chip *chip,int block,uint8_t mark)
{
    uint8_t msk = (mark & BBT_ENTRY_MASK) << ((block & BBT_ENTRY_MASK) * 2);
    chip->bbt[block >> BBT_ENTRY_SHIFT] |= msk;
}
我写了一个类似的程序来验证:

/*
 * Copyright: (C) 2014 fulinux <fulinux@sina.com>
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uint8_t bbt[10];

void bbt_mark_entry(uint8_t *bbt,int block)
{
        uint8_t msk = (0x03 & 0x03) << ((block & 0x03) * 2);
            bbt[block >> 2] |= msk;
}

uint8_t bbt_get_entry(uint8_t *bbt,int block)
{
        uint8_t entry = bbt[block >> 2];
            entry >>= (block & 0x3) * 2;
                return entry & 0x3;
}

/*
 *  
 */
int main (int argc,char **argv)
{
    uint8_t a;
    bbt_mark_entry(bbt,5);
    bbt_mark_entry(bbt,7);
    bbt_mark_entry(bbt,2);

    a = bbt_get_entry(bbt,5);

    printf("a = %dn",a);

    int i;
    for(i = 0; i < 10; i++){
        printf("0x%Xn",bbt[i]);
    }

    return 0;
} /* -----End of main()----- */

结果:

?./bbt-test ? ?
a = 3
0x30
0xCC
0x0
0x0
0x0
0x0
0x0
0x0
0x0
0x0

二进制为:

1100110000110000

说明是正确的。


最后的解决方法:

在drivers/mtd/nand/nand_util.c文件中添加如下函数:

#define cpu_to_je16(x) (x)
#define cpu_to_je32(x) (x)

+ static int nand_block_bad_scrub(struct mtd_info *mtd,loff_t ofs,int getchip)
+ {
+         return 0;
+ }

再在nand_erase_opts函数中作如下修改:

int percent_complete = -1;
+ int (*nand_block_bad_old)(struct mtd_info *,loff_t,int) = NULL;
const char *mtd_device = meminfo->name;

还有:

    if (opts->scrub) {
        erase.scrub = opts->scrub;
+         nand_block_bad_old = chip->block_bad;
+         chip->block_bad = nand_block_bad_scrub;
        /*
? ? ? ? ?* We don't need the bad block table anymore...
? ? ? ? ?* after scrub,there are no bad blocks left!
? ? ? ? ?*/
? ? ? ? if (chip->bbt) {
? ? ? ? ? ? kfree(chip->bbt);
? ? ? ? }
? ? ? ? chip->bbt = NULL;
最后:

+     if(nand_block_bad_old){
+         chip->block_bad = nand_block_bad_old;
+     }

? ? if (opts->scrub)
? ? ? ? chip->scan_bbt(meminfo);

上面修改的意思是既然要将nand恢复出厂设置,那就不必要再去检测要擦出的函数是否是坏块了,所以把以前的那个检测是否是坏块的函数指针保存起来,在将其chip->block_bad指针指向了nand_block_bad_scrub函数,该函数什么都没做就返回了。同时将bbt清空,置为NULL,这在后面的

static int nand_block_checkbad(struct mtd_info *mtd,int getchip,int allowbbt)
{
    struct nand_chip *chip = mtd->priv;

    if (!chip->bbt){
        return chip->block_bad(mtd,ofs,getchip);
    }

    /* Return info from the table */
    return nand_isbad_bbt(mtd,allowbbt);
}
函数中因为chip->bbt == NULL而执行chip->block_bad函数,但是该函数在上面已经换成的了一个什么都没做的nand_block_bad_scrub函数。所以不会返回有坏块。在nand_erase_nand函数中就不会因为调用nand_block_checkbad函数而始终擦除不了被标识的会快而出现问题了。


恢复出厂设置后,再将前面chip->block_bad指针重新指向先前的函数,同时再分配bbt区域,并重新扫描一下是否有坏块。

演示:

[TQ2440 #] nand bad


Device 0 bad blocks:
[TQ2440 #] nand markbad 0
block 0x00000000 successfully marked as bad
[TQ2440 #] nand scrub 0 4000


NAND scrub: device 0 offset 0x0,size 0x4000
Warning: scrub option will erase all factory set bad blocks!
? ? ? ? ?There is no reliable way to recover them.
? ? ? ? ?Use this command only for testing purposes if you
? ? ? ? ?are sure of what you are doing!


Really scrub this NAND flash? <y/N>
y
Erasing at 0x0 -- 100% complete.
OK

明天继续。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读