flash_erase擦除NAND flash坏块失败

转自 http://blog.csdn.net/yuanlulu/article/details/7339895


板子使用busybox文件系统,带了mtd-utils的工具,包括flash_erase。首先查看帮助信息:

[root@M3250 ~]# flash_erase --h
Usage: flash_erase [options] MTD_DEVICE
Erase blocks of the specified MTD device.
Specify a count of 0 to erase to end of device.
  -j, --jffs2       format the device for jffs2
  -N, --noskipbad   don't skip bad blocks
  -u, --unlock      unlock sectors before erasing
  -q, --quiet       display progress messages
      --silent      same as --quiet
      --help        display this help and exit
      --version     output version information and exit
[root@M3250 ~]#


看样子flash_erase默认不擦除坏块的,但可以使用-N选项启用这个功能。但是结果如下:

[root@M3250 ~]# flash_erase -N /dev/mtd4 0 0
Erasing 128 Kibyte @ 0 --  0 % nand_erase_nand: attempt to erase a bad block at page 0x0001ff00
Erasing 128 Kibyte @ 2nand_erase_nand: attempt to erase a bad block at page0x0001ff40
Erasing 128 Kibyte @ 40000 -- 50 % complete libmtd: error!: MEMERASE64 ioctl failed for eraseblock 2
 (mtd4)
        error 5 (Input/output error)
flash_erase: error!: /dev/mtd4: MTD Erase failure
             error 5 (Input/output error)
Erasing 128 Kibyte @ 60000 -- 75 % complete libmtd: error!: MEMERASE64 ioctl failed for eraseblock 3
 (mtd4)
        error 5 (Input/output error)
flash_erase: error!: /dev/mtd4: MTD Erase failure
             error 5 (Input/output error)
Erasing 128 Kibyte @ 60000 -- 100 % complete


还是擦不了。看了下内核的代码,在/drivers/mtd/nand/nand_base.c中nand_erase_nand函数有这么一段:

while (len) {
/*
* heck if we have a bad block, we do not erase bad blocks !
*/
if (nand_block_checkbad(mtd, ((loff_t) page) << chip->page_shift, 0, allowbbt)) {
printk(KERN_WARNING "%s:attempt to erase a bad block "
"at page 0x%08x\n", __func__, page);
instr->state = MTD_ERASE_FAILED;
goto erase_exit;
}

结论就是linux内核不支持擦除坏块。

解决办法:在uboot中使用"nand scrub"擦除。


附上自己写的mtd擦除程序:

[cpp]  view plain copy print ?
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6.   
  7. int main(int argc, char *argv[])  
  8. {  
  9.         int dev_fd;  
  10.         int result;  
  11.         erase_info_t erase;  
  12.         mtd_info_t mtd;  
  13.         int rt = 0;  
  14.   
  15.         if (argc !=2) {  
  16.                 printf("%s:input a argument like /dev/mtdX\n", argv[0]);  
  17.                 rt = -1;  
  18.                 goto exit;  
  19.         }  
  20.         printf("the device you want to erase is %s\n", argv[1]);  
  21.   
  22.         dev_fd = open (argv[1], O_SYNC | O_RDWR);  
  23.         if (dev_fd < 0) {  
  24.                 printf("open %s failed\n", argv[1]);  
  25.                 perror("erase mtd");  
  26.                 rt =  -1;  
  27.                 goto exit;  
  28.         }  
  29.   
  30.         if (ioctl(dev_fd, MEMGETINFO, &mtd) < 0) {  
  31.                 printf("%s:MTD getinfo failed\n", argv[1]);  
  32.                 perror("get mtd info");  
  33.                 rt = -1;  
  34.                 goto close;  
  35.         }  
  36.   
  37.         erase.start = 0;  
  38.         erase.length = mtd.size;            
  39.                                               
  40.         if (ioctl (dev_fd, MEMERASE, &erase) < 0) {  
  41.                 printf("%s: erase failed\n", argv[1]);  
  42.                 perror("erase mtd");  
  43.                 rt = -1;  
  44.                 goto close;  
  45.         }  
  46.         printf("erase %s sucess\n", argv[1]);  
  47.   
  48. close:  
  49.         close(dev_fd);  
  50. exit:  
  51.         return rt;  
  52. }  

你可能感兴趣的:(系统探究)