Reserved for bad PEB handling:不同NAND大小造成分区可用空间差异
在调试一个UBI设备时,需要调整MTD分区到尽量小。在调试完成后,换另一个型号NAND,挂载分区异常。记录一下定位问题过程。
1 大容量NAND挂载出现异常现象
同样ubifs文件系统镜像,写入同样NAND硬件,但是Reserved Physical Eraseblocks数量不同,进而导致ubifs的可用空间差异,挂载ubifs失败问题定位。
在ubi挂载的时候:
[ 2.427796] 000: ubi1: scanning is finished [ 2.444453] 000: ubi1 warning: ubi_eba_init: cannot reserve enough PEBs for bad PEB handling, reserved 35, need 40--实际需要40个,但只有35个可以使用。 [ 2.456870] 000: ubi1: attached mtd6 (name "amt", size 14 MiB) [ 2.456906] 000: ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes [ 2.456923] 000: ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 512 [ 2.456936] 000: ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096 [ 2.456950] 000: ubi1: good PEBs: 112, bad PEBs: 0, corrupted PEBs: 0 [ 2.456963] 000: ubi1: user volume: 1, internal volumes: 1, max. volumes count: 128 [ 2.456976] 000: ubi1: max/mean erase counter: 1/0, WL threshold: 4096, image sequence number: 116654442 [ 2.456993] 000: ubi1: available PEBs: 0, total reserved PEBs: 112, PEBs reserved for bad PEB handling: 35
经过UBI层消耗掉4+35=39个PEB。
ubifs挂载时:
[ 4.609343] 000: UBIFS (ubi1:0): Mounting in unauthenticated mode [ 4.609389] 000: UBIFS error (ubi1:0 pid 60): ubifs_read_superblock: too large journal size (8388608 bytes), only 7872512 bytes available in the main area--由于可用LEB变小,ubifs journal空间不够。 [ 4.609435] 000: UBIFS error (ubi1:0 pid 60): ubifs_read_superblock: bad superblock, error 1 [ 4.609460] 000: magic 0x6101831 [ 4.609469] 000: crc 0x4da62286 [ 4.609476] 000: node_type 6 (superblock node) [ 4.609484] 000: group_type 0 (no node group) [ 4.609493] 000: sqnum 2084 [ 4.609499] 000: len 4096 [ 4.609506] 000: key_hash 0 (R5) [ 4.609514] 000: key_fmt 0 (simple) [ 4.609521] 000: flags 0x4 [ 4.609527] 000: big_lpt 0 [ 4.609533] 000: space_fixup 1 [ 4.609539] 000: min_io_size 2048 [ 4.609545] 000: leb_size 126976 [ 4.609552] 000: leb_cnt 73--当前可用LEB数量。 [ 4.609558] 000: max_leb_cnt 596--最大LEB数量。 [ 4.609564] 000: max_bud_bytes 8388608 [ 4.609571] 000: log_lebs 5 [ 4.609576] 000: lpt_lebs 2 [ 4.609582] 000: orph_lebs 1 [ 4.609588] 000: jhead_cnt 1 [ 4.609594] 000: fanout 8 [ 4.609599] 000: lsave_cnt 256 [ 4.609605] 000: default_compr 1 [ 4.609611] 000: rp_size 0 [ 4.609617] 000: rp_uid 0 [ 4.609623] 000: rp_gid 0 [ 4.609628] 000: fmt_version 4 [ 4.609634] 000: time_gran 1000000000 [ 4.609642] 000: UUID 5090B793-C301-4AE9-83EE-5BAC5B8DF3A5
通过ubinfo查看当前ubi信息:
ubinfo /dev/ubi1 ubi1 Volumes count: 1 Logical eraseblock size: 126976 bytes, 124.0 KiB Total amount of logical eraseblocks: 112 (14221312 bytes, 13.5 MiB)--LEB总数。112-4(UBI管理所需)=108 Amount of available logical eraseblocks: 0 (0 bytes) Maximum count of volumes 128 Count of bad physical eraseblocks: 0 Count of reserved physical eraseblocks: 35--预留坏块管理的PEB数量。108-35=73,还剩73个LEB可用。 Current maximum erase counter value: 1 Minimum input/output unit size: 2048 bytes Character device major/minor: 248:0 Present volumes: 0
2 问题定位
检查代码发现,即使UBI分区建立在一个MTD分区上,坏块管理预留PEB数量任然是按照总的NAND PEB数量*20/1024。
ubi_init ->ubi_attach_mtd_dev
->max_beb_per1024--此变量表示每1024个PEB中使用多少PEB作为坏块管理。最大是MAX_MTD_UBI_BEB_LIMIT,没有设置则使用默认CONFIG_MTD_UBI_BEB_LIMIT。 ->io_init ->get_bad_peb_limit--根据max_beb_per1024计算UBI需要多少PEB来维护坏块管理。 ->mtd_get_device_size--获取整个NAND设备的大小。 ->mtd_div_by_eb--计算整个NAND设备的EB数量,所以这里计算预留的EB数量是根据NAND总的EB数*20/1024。
->ubi_attach
->ubi_eba_init
->ubi_calculate_reserved--计算ubi->beb_rsvs_level数量。
->print_rsvd_warning--如果ubi->avail_pebs小于ubi->beb_rsvd_level则打印警告。
所以每一个UBI设备,128MB NAND需要预留20 PEB作为坏块管理;256MB NAND需要预留40个PEB;512MB NAND需要预留80个PEB。
有下面代码可以看出一个UBI设备的浪费空间确实较大:

3. 解决方法
在MTD分区上做UBI时,需要考虑不同NAND大小的影响:
- 根据《Flash space overhead》描述,每一个NAND UBI分区需要占用4 PEB,另外根据《Reserved blocks for bad block handlong (only for NAND chips)》描述,NAND设备的20/1024作为坏块管理。代价太大,所以尽量少UBI设备,可以多个volume。
- 配置CONFIG_MTD_UBI_BEB_LIMIT,降低预留给坏块管理的PEB比例。
- 增加MTD分区PEB数量,保留足够的坏块管理PEB。
联系方式:arnoldlu@qq.com
浙公网安备 33010602011771号