基础概念
以uboot打印的信息为例:
SPI Nand(cs 0) ID: 0xc2 0x12 Name:"MX35LF1GE4AB"
Block:128KB Page:2KB Chip:128MB*1 OOB:64B ECC:4bit/512
ECC provided by Flash Memory Controller
block : 块大小,128Kb,每个块有64页
page:页大小,2K
oob:oob大小为,64字节,包含坏块标记,ecc校验数据
ecc:类型为4bit/512,代表不同的纠错能力
nandflash 结构图
问题案例
uboot查看坏块
hisilicon # nand bad
Device 0 bad blocks:
06ca0000
在uboot里面nand erase时,会自动跳过坏块。不用用户关心
nand erase 0x1500000 0x6100000; nand write 0x82000000 0x1500000 0x6100000
NAND erase: device 0 offset 0x1500000, size 0x6100000
Skipping bad block at-- 90% complete.
0x06ca0000
Erasing at 0x75e0000 -- 100% complete.
OK
NAND write: device 0 offset 0x1500000, size 0x6100000
********** cmd: write, s: <NULL>, nand_curr_device:0 name:MX35LF1GE4AB 0ff:0x8079f69c rw_size:0x:1500000, addr:0x0
pure data length is 101711872, len_incl_bad is 101842944
data length:0x6100000, include bad block length: 0x6120000
Skip bad block 0x06ca0000
101711872 bytes written: OK
nand flash坏块标记
nand markbad [地址]
举例:
hisilicon # nand markbad 0x2dc0000
block 0x02dc0000 successfully marked as bad
hisilicon # nand bad
Device 0 bad blocks:
02dc0000
06ca0000
读取nand信息
nand dump [大小] //无论这里写多大,都是读取一页的信息外加oob的信息
以下是正常的好块的数据的信息
hisilicon # nand dump 0
Page 00000000 dump:
17 05 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5
...
ec c0 11 12 01 02 00 00 00 00 00 00 fd 00 00 00
OOB:
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff 00 00
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
以下是正常的坏块的数据的信息
hisilicon # nand dump 0x06ca0000
Page 06ca0000 dump:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
OOB:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
注意的是,只要这个块被标记为坏块,那么这个块中的所有页的oob都会被标记为非FF,具体那几位代表,坏块,有待之后继续研究
清除标记的坏块
nand scrub
值得注意的是,这里清除所有标记的坏块,并不会将真正的坏块清除,只会将手动标记的坏块,恢复。所以并不会造成不良的影响。
hisilicon # nand scrub
NAND scrub: device 0 whole chip
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>
scrub aborted
hisilicon # nand scrub
NAND scrub: device 0 whole chip
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>
Erasing at 0x6b80000 -- 84% complete.
MX35LF1GE4AB: MTD Erase failure: -5
Block at 0x06ca0000 is marked bad block
Erasing at 0x7fe0000 -- 100% complete.
OK
hisilicon # nand bad
Device 0 bad blocks:
06ca0000
mtd接口擦除发现坏块
坏快,需要用户自己进行跳过,提前判断是否是坏块,可以以下函数
297 static loff_t next_good_eraseblock(int fd, struct mtd_info_user *meminfo, loff_t block_off
set)
298 {
299 int ret = 0;
300
301 while (1)
302 {
303 loff_t offs = 0;
304
305 if (block_offset >= meminfo->size)
306 {
307 printf("not enough space in MTD device \n");
308 return block_offset; /* let the caller exit */
309 }
310
311 ret = ioctl(fd, MEMGETBADBLOCK, &block_offset);
312 if (ret == 0)
313 {
314 return block_offset;
315 }
316 else if (ret > 0)
317 {
318 /* ioctl returned 1 => "bad block" */
319 printf("Skipping bad block at 0x%08llx\n", block_offset);
320 block_offset += meminfo->erasesize;
321 }
322 else
323 {
324 printf("mtd ioctl err !!! \n");
325 }
326 }
327 }
因为坏块导致地址改变
### 因为对齐可能导致导致uboot无法启动