首先,理解一个3层的概念,mtd -> ubi -> ubifs
mtd是flash上的分区,单纯把一个flash分成n个区,这里没有任何数据的概念,也不需要分区表,比如128M的flash,前32M一个区,后96M一个区,就是一个线性分区。
ubi构建在一个mtd分区之上。ubi就有数据概念了,它有分区表,同时每个块,都会有一个ubi头,ubi维护擦写均衡,nand flash是有擦写寿命的,ubi的擦写均衡可以保证每个块的擦写次数均衡。
ubifs是一个文件系统,通常构建在ubi的分区之上,但是ubifs文件系统直接使用mtd的块设备,那也是可以的。
如何在一个mtd分区上构建ubi系统,并创建ubifs,并挂载呢?
比如,如下overlay分区,我们想创建ubifs,并挂载到/tmp/data。
# cat /proc/mtd
dev: size erasesize name
mtd0: 00080000 00020000 "0:SBL1"
mtd1: 00080000 00020000 "0:MIBIB"
mtd2: 00040000 00020000 "0:BOOTCONFIG"
mtd3: 00040000 00020000 "0:BOOTCONFIG1"
mtd4: 00100000 00020000 "0:QSEE"
mtd5: 00100000 00020000 "0:QSEE_1"
mtd6: 00040000 00020000 "0:DEVCFG"
mtd7: 00040000 00020000 "0:DEVCFG_1"
mtd8: 00040000 00020000 "0:CDT"
mtd9: 00040000 00020000 "0:CDT_1"
mtd10: 00080000 00020000 "0:APPSBLENV"
mtd11: 00140000 00020000 "0:APPSBL"
mtd12: 00140000 00020000 "0:APPSBL_1"
mtd13: 00100000 00020000 "0:ART"
mtd14: 00080000 00020000 "0:TRAINING"
mtd15: 00080000 00020000 "bdata"
mtd16: 00080000 00020000 "crash"
mtd17: 00080000 00020000 "crash_log"
mtd18: 02400000 00020000 "rootfs"
mtd19: 02400000 00020000 "rootfs_1"
mtd20: 01f00000 00020000 "overlay"
mtd21: 00d80000 00020000 "data"
mtd22: 00307000 0001f000 "kernel"
mtd23: 00bbf000 0001f000 "ubi_rootfs"
如上overlay mtd分区号是20。使用-m 20,也可以使用 -p /dev/mtd20,如果没有/dev,那只能使用-m方式。
# ubiattach -m 20
[55352.190294] ubi1: attaching mtd20
[55352.292540] ubi1: scanning is finished
[55352.292589] ubi1: empty MTD device detected
[55352.317937] ubi1: attached mtd20 (name "overlay", size 31 MiB)
[55352.317984] ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
[55352.324439] ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
[55352.329988] ubi1: VID header offset: 2048 (aligned 2048), data offset: 4096
[55352.336801] ubi1: good PEBs: 248, bad PEBs: 0, corrupted PEBs: 0
[55352.343555] ubi1: user volume: 0, internal volumes: 1, max. volumes count: 128
[55352.349758] ubi1: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 3283751418
[55352.356784] ubi1: available PEBs: 224, total reserved PEBs: 24, PEBs reserved for bad PEB handling: 20
[55352.366381] ubi1: background thread "ubi_bgt1d" started, PID 416
UBI device number 1, total 248 LEBs (31490048 bytes, 30.0 MiB), available 224 LEBs (28442624 bytes, 27.1 MiB), LEB size 126976 bytes (124.0 KiB)
ubiattach可以attach一个空白的mtd分区,也可以attach一个已经创建好ubi或ubifs的之前的mtd分区。attach之后,/sys/class/ubi/下面就会出现对应的条目了。比如上述ubi device number 是1,就会有
# ls /sys/class/ubi/ubi1
avail_eraseblocks eraseblock_size mtd_num subsystem
bad_peb_count max_ec power total_eraseblocks
bgt_enabled max_vol_count reserved_for_bad uevent
dev min_io_size ro_mode volumes_count
使用ubinfo可以查看,ubi信息:
# ubinfo -d 1
ubi1
Volumes count: 0
Logical eraseblock size: 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks: 248 (31490048 bytes, 30.0 MiB)
Amount of available logical eraseblocks: 224 (28442624 bytes, 27.1 MiB)
Maximum count of volumes 128
Count of bad physical eraseblocks: 0
Count of reserved physical eraseblocks: 20
Current maximum erase counter value: 1
Minimum input/output unit size: 2048 bytes
Character device major/minor: 248:0
如果ubiattach失败,通常不是一个空白的mtd,且mtd不是一个ubi,其数据不满足ubi的格式,此时mtd erase擦除mtd分区,再attach就可以了。
ubimkvol需要使用字符设备,对于上述ubi device number 1,为/dev/ubi1。通常attach后,udev会自动监听到,并创建/dev/ubi1。
如果没有创建,可以读取/sys/class/ubi/ubi1/dev获得设备的major和minor,然后使用mknod手动创建。
# cat /sys/class/ubi/ubi1/dev
248:0
# mknod /dev/ubi1 c 248 0
接下来使用ubimkvol创建,-m表示使用最大可用大小,这里我们只创建一个分区,使用全部的大小,分区名叫data。
# ubimkvol /dev/ubi1 -m -N data
Set volume size to 28442624
Volume ID 0, size 224 LEBs (28442624 bytes, 27.1 MiB), LEB size 126976 bytes (124.0 KiB), dynamic, name "data", alignment 1
创建完毕后,sys出现了 ubi1_0
# ls /sys/class/ubi/ubi1_0/
alignment device subsystem usable_eb_size
corrupted name type
data_bytes power uevent
dev reserved_ebs upd_marker
dev出现了ubi1_0,这个是该分区的字符设备,可用来创建、挂载文件系统。
同理,如果没有自动创建dev,可以读取/sys/class/ubi/ubi1_0/dev,获取major和minor后,手动mknod
# ls /dev/ubi1_0
/dev/ubi1_0
有了ubi分区,我们就可以创建、挂载ubifs了,但是对于一个空白的ubi分区,通常我们可以直接挂载
# mount -t ubifs /dev/ubi1_0 /tmp/data
[56719.260037] UBIFS (ubi1:0): default file-system created
[56719.260560] UBIFS (ubi1:0): Mounting in unauthenticated mode
[56719.264610] UBIFS (ubi1:0): background thread "ubifs_bgt1_0" started, PID 438
[56719.321489] UBIFS (ubi1:0): UBIFS: mounted UBI device 1, volume 0, name "data"
[56719.321543] UBIFS (ubi1:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
[56719.328008] UBIFS (ubi1:0): FS size: 27172864 bytes (25 MiB, 214 LEBs), max 224 LEBs, journal size 1396736 bytes (1 MiB, 11 LEBs)
[56719.337933] UBIFS (ubi1:0): reserved for root: 1283441 bytes (1253 KiB)
[56719.349554] UBIFS (ubi1:0): media format: w5/r0 (latest is w5/r0), UUID B8D78B72-B6FB-479A-A5A8-5F1667D9D636, small LPT model
这两种方式也可以:
mount -t ubifs ubi1_0 /tmp/data
删除/dev/ubi1_0,仍然可以挂载
mount -t ubifs ubi1:data /tmp/data
同ubi1_0一样,也不依赖/dev/ubi1_0