首页 > 代码库 > UBIFS学习笔记

UBIFS学习笔记

在做项目的时候,发现flash芯片有异常现象,经过打印分析,发现是UBIFS方面设置有一些问题,经过查阅一部分资料,最终得到问题的答案。

在解决问题的过程中,发现打印信息比较重要,但网上并没有直接的相关资料,最后将自己总结的东西总结如下:

先看打印信息,打印信息如下:

UBI: attaching mtd3 to ubi3

UBI: physical eraseblock size:  131072 bytes (128 KiB)

UBI: logical eraseblock size:   126976 bytes

UBI: smallest flash I/O unit:   2048

UBI: VID header offset:         2048 (aligned 2048)

UBI: data offset:               4096

UBI: MTD device name:           "data"

UBI: MTD device size:           4 MiB

UBI: number of good PEBs:       30

UBI: number of bad PEBs:        2

UBI: max. allowed volumes:      128

UBI: wear-leveling threshold:   4096

UBI: number of internal volumes: 1

UBI: number of user volumes:    0

UBI: available PEBs:            24

UBI: total number of reserved PEBs: 6

UBI: number of PEBs reserved for bad PEB handling: 2

UBI: max/mean erase counter: 1/1

UBI: image sequence number: 0

UBI device number 3, total 30 LEBs (3809280 bytes, 3.6 MiB), available 24 LEBs (3047424 bytes, 2.9 MiB), LEB size 126976 bytes (124.0 KiB)

Junior create data volume

UBI error: ubi_create_volume: cannot create volume 0, error -28

ubimkvol: error!: cannot UBI create volume

         error 28 (No space left on device)

可知,在UBIFS文件系统下由于申请空间过大导致文件挂载失败,进而出现这种现象。

问题分析:

在分析问题之前,需要先结合打印信息简单的了解一下UBIFS。UBIFS只工作于UBI volume之上。也可以说,UBIFS涉及了三个子系统:

MTD系统,提供对flash芯片的访问接口;

UBI系统,工作在MTD上,提供UBI volume;

UBIFS文件系统,工作在UBI之上。

基于这种层次结构,底层MTD的物理分区(PEB)和上层逻辑分区(LEB)有映射关系,这样做的好处是在上层读写数据时不会考虑底层坏块的影响。

先看物理分区(PEB),每个PEB上都会有两个64bytes的头,这俩头部分别是EC header和VID header,对一片flash芯片而言,如果没有sub-pages,那么EC header会存储于第一个page,VID header会存储于第二个page。因此LEB要比PEB要小一些,如打印所示:

UBI: physical eraseblock size:  131072 bytes (128 KiB)

UBI: logical eraseblock size:   126976 bytes

UBI: smallest flash I/O unit:   2048

UBI: VID header offset:         2048 (aligned 2048)

UBI: data offset:               4096

UBI: attached mtd3 to ubi3

UBI: MTD device name:           "data"

UBI: MTD device size:           4 MiB

UBI: number of good PEBs:       30

UBI: number of bad PEBs:        2

针对这个打印,我们可以看到,此flash芯片PEB为131072 bytes(128KiB),在4MiB的分区里共有32片PEB,其中2片PEB标记坏块。每块PEB,除去EC header和VID header所占的空间4096 bytes(可从VID header的偏移位置和data的偏移位置看出),LEB最终容量为126976 bytes(124KiB)。

另外,UBI系统运行时,其本身也会占用一部分flash空间,从而使得用户能使用的flash容量减少。这些flash空间包括:

2片PEB用于存储卷表(volume table)。卷表是一种数据结构,包含了UBI设备上每一卷的信息,它是一系列volume table record,其中每一个记录块上包含以下信息:卷大小(volume size)、卷名(volume name)、卷类型(volume type,dynamic or static)、volume alignment、更新标记(update marker,防止数据更新发生意外打断,可以恢复)、自重整大小旗标(auto-resize flags)、CRC-32 校验和等信息。之所以保留两份卷表,是为了提高稳定性和防止出现突然断电的状况。当访问MTD设备时,UBI需要确保两个卷表是一致的,如果由于掉电或意外重启导致任何一种不一致状况,需要用较旧的卷表覆盖较新的卷表,确保一致;一旦有一个卷表损坏,可以使用另一个卷表。这俩卷表对用户来说,是不可见和不可访问的。

1片PEB用于损耗平衡(wear-leaving)。UBI支持损耗平衡,这对有限次读写的flash来说可极大提高其使用寿命。在UBI模块中,会包含一个负责实现损耗平衡的独立损耗均衡单元,这个单元依据EC header和VID header来实现对每个物理擦除块所擦除的次数和所属逻辑单元的读取,利用红黑树法对每个擦除块进行保护和移动。

1片PEB用于atomic LEB change operation(不知道是干什么的)

还有一部分PEB用于保存坏块的句柄,针对这个型号的flash,有2片PEB用于保存坏块句柄(见打印信息)。

因此,对于这个型号的flash芯片,总共要分出6片PEB用于支持UBI系统的运行。

结论

了解到了这些信息,回归到问题上来。结合打印信息可知,这个分区总共有4MiB的空间,有30片PEB可用,其中要分出6片PEB以供UBI运行时使用,还剩24片PEB用来存储数据。每片PEB可用存储124KiB的数据,也就是最大能储存24*124KiB=2976KiB(约2.9MiB)的数据,如果申请3MiB的空间,势必会因分区空间不足而导致文件挂载失败。

为此,可以考虑缩小申请空间,使其不大于2.9MiB(UBIFS只识别整数形式的GiB、MiB、KiB,修改的时候需注意这一点),这样的话,文件挂载便不会失败,问题就可以解决了。

UBIFS学习笔记