最近的一块板上使用了一颗大容量的NAND Flash,MLC架构,内核启动时,显示相关信息如下:
nand: device found, Manufacturer ID: 0x2c, Chip ID: 0x88
nand: Micron MT29F64G08CBAAAWP
nand: 8192 MiB, MLC, erase size: 2048 KiB, page size: 8192, OOB size: 448
4 fixed-partitions partitions found on MTD device atmel_nand
Creating 4 MTD partitions on "atmel_nand":
0x000000400000-0x000001400000 : "device tree"
0x000001400000-0x000002000000 : "kernel"
0x000002000000-0x000040000000 : "rootfs"
0x000040000000-0x000200000000 : "database"
ubinize需要指定一个配置文件,内容如下:
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=768MiB
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_flags=autoresize
- 1、ubifs镜像的制作:
# mkfs.ubifs -x lzo -m 8KiB -e 2032KiB -c 496 -o ubifs.img -d rootfs
# ubinize -o rootfs.ubi -m 8KiB -p 2048KiB -s 8KiB -O 8192 ubinize.cfg -v
ubinize: LEB size: 2080768
ubinize: PEB size: 2097152
ubinize: min. I/O size: 8192
ubinize: sub-page size: 8192
ubinize: VID offset: 8192
ubinize: data offset: 16384
ubinize: UBI image sequence number: 662004650
ubinize: loaded the ini-file "ubinize.cfg"
ubinize: count of sections: 1
ubinize: parsing section "ubifs"
ubinize: mode=ubi, keep parsing
ubinize: volume type: dynamic
ubinize: volume ID: 0
ubinize: volume size: 805306368 bytes
ubinize: volume name: rootfs
ubinize: volume alignment: 1
ubinize: autoresize flags found
ubinize: adding volume 0
ubinize: writing volume 0
ubinize: image file: ubifs.img
ubinize: writing layout volume
ubinize: done
因NAND中有坏块,未完成退出。查看代码发现NAND Erase不能擦除坏块,遇到坏块时退出。
找到源码文件"./drivers/mtd/nand/raw/nand-base.c"中函数 "nand_erase_nand"体部分,
摘录代码如下:
while (len) {
/* Check if we have a bad block, we do not erase bad blocks! */
if (nand_block_checkbad(mtd, ((loff_t) page) <<
chip->page_shift, allowbbt)) {
pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
__func__, page);
ret = -EIO;
goto erase_exit;
}
……
修改为跳过坏块继续擦除,代码如下:
while (len) {
/* Check if we have a bad block, we do not erase bad blocks! */
if (nand_block_checkbad(mtd, ((loff_t) page) <<
chip->page_shift, allowbbt)) {
pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
__func__, page);
// ret = -EIO;
// goto erase_exit;
/* Increment page address and decrement length */
len -= (1ULL << chip->phys_erase_shift);
page += pages_per_block;
continue;
}
……
重新编译后,执行ubiformat:
# ubiformat /dev/mtd7 -s 8192 -O 8192 -f rootfs.ubi
ubiformat: mtd7 (mlc-nand), size 8556380160 bytes (8.0 GiB), 4080 eraseblocks of 2097152 bytes (2.0 MiB), min. I/O size 8192 bytes
libscan: scanning eraseblock 4079 -- 100 % complete
ubiformat: 74 eraseblocks have valid erase counter, mean value is 0
ubiformat: 4002 eraseblocks are supposedly empty
ubiformat: warning!: 4 of 4080 eraseblocks contain non-ubifs data
ubiformat: continue? (yes/no) y
ubiformat: warning!: only 74 of 4080 eraseblocks have valid erase counter
ubiformat: erase counter 0 will be used for all eraseblocks
ubiformat: note, arbitrary erase counter value may be specified using -e option
ubiformat: continue? (yes/no) y
ubiformat: use erase counter 0 for all eraseblocks
ubiformat: flashing eraseblock 28 -- 100 % complete
ubiformat: formatting eraseblock 70 -- 1 % complenand: biformat: formatting eraseblock 71 -- 1 % cubiformat: formatting eraseblock 73 -- 1 % complete nand_erase_nand: attempt to erase a bad block at page 0x00005a00
ubiformat: fnamatting eraseblock 74 -- 1 % complete nd: nand_erase_nand: attempt to erase a bad block at page 0x00005b00
ubiformat: formatting eraseblock 4048 -- 99 % complete and: nand_erase_nand: attempt to erase a bad block at page 0x000ffc00
ubiformat: formatting eraseblock 406d: nand_erase_nand: attempt to erase a bad block at page 0x000ffd00
ubiformat: formatting eraseblock 4077 -- 99 % complete and: nand_erase_nand: attempt to erase a bad block at page 0x000ffe00
ubiformat: formanand: nraseblock 4078 -- 99 % complete and_erase_nand: attempt to erase a bad block at page 0x000fff00
ubiformat: formatting eraseblock 4079 -- 100 % complete
ubiattach /dev/ubi_ctrl -m 7 -O 8192
ubi: refuse attaching mtd7 - MLC NAND is not supported
经查,发现高版本内核已屏蔽对MLC NAND的支持。对比linux-4.9.36,没有屏蔽MLC,跳过下面这段代码:源码文件"./drivers/mtd/ubi/build.c"中函数 “ubi_attach_mtd_dev”
if (mtd->type == MTD_MLCNANDFLASH) {
pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n",
mtd->index);
return -EINVAL;
}
重新编译后,执行:
# ubiattach /dev/ubi_ctrl -m 7 -O 8192
ubi0: default fastmap pool size: 20
ubi0: default fastmap WL pool size: 10
ubi0: attaching mtd7
ubi0: scanning is finished
gluebi (pid 153): gluebi_resized: got update notification for unknown UBI device 0 volume 0
ubi0: volume 0 ("rootfs") re-sized from 388 to 410 LEBs
ubi0: attached mtd7 (name "rootfs", size 992 MiB)
ubi0: PEB size: 2097152 bytes (2048 KiB), LEB size: 2080768 bytes
ubi0: min./max. I/O unit sizes: 8192/8192, sub-page size 8192
ubi0: VID header offset: 8192 (aligned 8192), data offset: 16384
ubi0: good PEBs: 494, bad PEBs: 2, corrupted PEBs: 0
ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 773013103
ubi0: available PEBs: 0, total reserved PEBs: 494, PEBs reserved for bad PEB handling: 78
ubi0: background thread "ubi_bgt0d" started, PID 154
UBI device number 0, total 494 LEBs (1027899392 bytes, 980.3 MiB), available 0 LEBs (0 bytes), LEB size 2080768 bytes (2.0 MiB)
重启目标板,在u-boot中设置rootfs为此分区,linux正常启动。
总结:为什么在高版本内核中暂时放弃MLC支持,肯定是有原因的,目前的几块测试板暂时先这样吧,下版用eMMC 换掉 MLC NAND。