如何构建UBIFS镜像来利用MTD的剩余空间?

如何构建UBIFS镜像来利用MTD的剩余空间?

我正在开发嵌入式 Linux 系统(kernel-5.24),开发主机在 Windows 中运行 WSL2。

嵌入式系统中有一块128MB的NAND FLASH(PEB为128KiB,页大小为4096字节,有1024个PEB)。现在我想使用 ubinize 在 MTD2 上创建一个 UBIFS 卷,这是最后一个 MTD 分区,其大小为 0x7700000 (119MiB)。

这是我正在使用的 ubinize.cfg,

[ubifs]
mode=ubi
image=ubifs.rootfs
vol_id=0
vol_size=119MiB
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_flags=autoresize

命令如下,

ubinize -m 2048 -p 128KiB -s 512 -O 2048 ./ubinize.cfg -v -o ubi.img

然后我部署了生成的ubi.img,系统启动时出现错误,如下,

[    2.138286] ubi0: attaching mtd2
[    2.315180] ubi0: scanning is finished
[    2.322753] ubi0 error: vtbl_check: too large reserved_pebs 983, good PEBs 952
[    2.330258] ubi0 error: vtbl_check: volume table check failed: record 0, error 9
[    2.337904] Volume table record 0 dump:
[    2.341878]  reserved_pebs   983
[    2.345202]  alignment       1
[    2.348354]  data_pad        0
[    2.351515]  vol_type        1
[    2.354663]  upd_marker      0
[    2.357812]  name_len        6
[    2.360976]  name            rootfs
[    2.364572]  crc             0xd6e9ec58
[    2.368727] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd2, error -22
[    2.376054] UBI error: cannot attach mtd2

于是通过网上查了一下,为了利用整个MTD2分区,我修改了ubinize.cfg,没有进行vol_size如下设置,

[ubifs]
mode=ubi
image=system.ubifs
vol_id=0
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_flags=autoresize

这样,内核可以启动,rootfs可以正确安装,并ubinfo显示以下内容,

# ubinfo -a
UBI version:                    1
Count of UBI devices:           1
UBI control device major/minor: 10:63
Present UBI devices:            ubi0

ubi0
Volumes count:                           1
Logical eraseblock size:                 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks:     952 (120881152 bytes, 115.2 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  20
Current maximum erase counter value:     2
Minimum input/output unit size:          2048 bytes
Character device major/minor:            248:0
Present volumes:                         0

Volume ID:   0 (on ubi0)
Type:        dynamic
Alignment:   1
Size:        928 LEBs (117833728 bytes, 112.3 MiB)
State:       OK
Name:        rootfs
Character device major/minor: 248:1

我有以下问题:总共有 952 个 LEB,但ubinfo -a显示使用了 928 个 LEB。是否用完整个 119MB 分区?
此配置中可以使用的 LEB 的最大数量是多少?
如何规划此 NAND 配置中的 UBIFS 大小(1024 PEB,最大坏块为 20,并考虑磨损均衡)?

答案1

通过阅读FLASH空间开销经过测试和尝试,我弄清楚了 ubinize.cfg 中数字的含义和设置,如下所示。

首先,vol_sizeubinize.cfg 中指定了 UBI 卷的实际数据 LEB 的大小。它不计入 4 个 PEB(LEB)的开销。因此指定vol_size=119MiB是错误的,因为它超出了数据 LEB 的大小。

在我的例子中,总共还剩下 952 个 PEB rootfs,其中 20 个 PEB 保留用于坏块,4 个 PEB 是开销,因此只有 928 个 PEB 剩余用于实际数据块 (LEB),因此实际大小应该是928*126976=117833728,这与 的结果相匹配ubinfo -a

其次,autoresize=1如果我设置的话, ubinize 会自动调整 UBI 卷的大小vol_size=106MiB,并且我可以获得与上面相同的大小(928 LEB)。如果没有autoresize=1,结果如下所示,与上面不同。

# ubinfo -a
UBI version:                    1
Count of UBI devices:           1
UBI control device major/minor: 10:63
Present UBI devices:            ubi0

ubi0
Volumes count:                           1
Logical eraseblock size:                 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks:     952 (120881152 bytes, 115.2 MiB)
Amount of available logical eraseblocks: 52 (6602752 bytes, 6.2 MiB)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  20
Current maximum erase counter value:     2
Minimum input/output unit size:          2048 bytes
Character device major/minor:            248:0
Present volumes:                         0

Volume ID:   0 (on ubi0)
Type:        dynamic
Alignment:   1
Size:        876 LEBs (111230976 bytes, 106.0 MiB)
State:       OK

106MiB 由 876 个 LEB 组成,这与我上面所做的计算相符。

最后,单位vol_size也可以是KiB,这对于对UBI卷的大小进行更精细的调整/规划非常有用。

相关内容