1. UBI文件系统的概念
1.1 UBI文件系统
UBIFS是由诺基亚工程师在塞格德大学的帮助下开发的一种新的闪存文件系统。在某种程度上,UBIFS可以被认为是JFFS2文件系统的下一代。
UBI 意思是"Unsorted Block Images未排序的块镜像"。UBIFS是一个flash文件系统。UBIFS与Linux中的传统文件系统如Ext2,XFS,JFS等完全不同。UBIFS 表示一类单独的文件系统,它们与 MTD 设备(而不是块设备)一起使用。此类的另一个 Linux 文件系统是 JFFS2。
1.2 UBIFS涉及三个子系统
1)MTD子系统:flash驱动直接操作设备,而MTD在flash驱动之上,向上呈现统一的操作接口。所以MTD子系统的使命是:屏蔽不同flash的操作差异,向上提供统一的操作接口;对应drivers/mtd;
2)UBI子系统:UBI子系统是基于MTD子系统的,在MTD上实现nand特性的管理逻辑,向上屏蔽nand的特性;对应drivers/mtd/ubi;
3)UBIFS文件系统:是基于UBI子系统的文件系统,实现文件系统的所有基本功能。例如文件的实现,日志的实现;对应fs/ubifs; JFFS2 文件系统在 MTD 设备之上工作,但 UBIFS 在 UBI 卷之上工作,不能在 MTD 设备上运行。换句话说,涉及 3 个子系统:
MTD子系统,提供统一的接口来访问闪存芯片。MTD提供了MTD设备的概念(例如,),它基本上代表原始闪存;/dev/mtd0 UBI子系统,它是闪存设备的磨损均衡和卷管理系统;UBI在MTD设备之上工作,并提供UBI数量的概念;UBI卷是比MTD设备更高级别的实体,它们没有MTD设备具有的许多令人不快的问题(例如,磨损和坏块);有关更多信息,请参阅此处; UBIFS 文件系统,它工作在 UBI 卷之上。
1.3 UBIFS 功能
以下是一些 UBIFS 功能的列表:
可扩展性 - UBIFS相对于闪存大小具有良好的可扩展性;即,挂载时间,内存消耗和I / O速度不取决于闪存大小(目前对于内存消耗来说不是100%,但依赖性非常弱,这可能是固定的);UBIFS(不是UBI!)应该可以正常工作数百个GiB闪光灯;但是,UBIFS依赖于具有可扩展性限制的UBI(请参阅此处);尽管如此,UBI / UBIFS堆栈的扩展性比JFFS2好得多,如果UBI成为瓶颈,则始终可以在不更改UBIFS的情况下实现UBI2; 快速安装 - 与JFFS2不同,UBIFS在安装时不必扫描整个介质,UBIFS需要几毫秒才能安装介质,这不取决于闪存大小;但是,UBI初始化时间取决于闪存大小; 写回支持 - 与JFFS2相比,这大大提高了许多工作负载中文件系统的吞吐量,JFFS2是直写 容忍不干净的重新启动 - UBIFS是一个日志文件系统,它容忍突然崩溃和不干净的重新启动;UBIFS只是重播日志并从不干净的重启中恢复;在这种情况下,挂载时间稍慢,因为需要重放日志,但 UBIFS 不需要扫描整个介质,因此挂载 UBIFS 无论如何都需要几分之一秒的时间; 快速I / O - 即使禁用了回写(例如,如果使用""挂载选项安装UBIFS),UBIFS也表现出良好的性能,接近JFFS2性能;请记住,在同步I/O中与JFFS2竞争是极其困难的,因为JFFS2不在闪存上维护索引数据结构,因此它没有维护开销,而UBIFS确实有它;但是UBIFS仍然很快,因为UBIFS提交日志的方式 - 它不会将数据从一个地方物理移动到另一个地方,而是将相应的信息添加到文件系统索引中,并为新日志选择不同的擦除块(即,UBIFS具有某种"徘徊"日志,不断改变位置);还有其他技巧,如多头日记,使UBIFS表现良好;-o sync 动态压缩 - 数据以压缩形式存储在闪存介质上,这使得将比未压缩数据更多的数据放入闪存成为可能;这与JFFS2非常相似;UBIFS还允许在每个inode的基础上打开/关闭压缩,这非常灵活;例如,默认情况下可以关闭压缩,并仅对应该压缩良好的某些文件启用压缩;或者可以默认打开压缩,但对于所谓的不可压缩数据(如多媒体文件)禁用它;目前,UBIFS仅支持zlib和LZO压缩机,并且不难添加更多;有关详细信息,请参阅此部分。 可恢复性 - 如果索引信息损坏,UBIFS 可能会被完全恢复;UBIFS中的每条信息都有一个描述该信息段的标头,并且可以通过扫描闪存介质完全重建文件系统索引;这与JFFS2非常相似;为了更清楚地说明,您已经清除了FAT文件系统上的FAT表;对于FAT FS来说,这将是致命的;但是,如果您同样清除了UBIFS索引,您仍然可以重新构建它,尽管需要一个特殊的用户空间工具来执行此操作(尽管目前尚未实现此实用程序); 完整性 - UBIFS(以及UBI)校验和它写入闪存介质的所有内容以保证数据完整性,UBIFS不会让数据或元数据损坏被忽视(JFFS2也在做同样的事情);默认情况下,UBIFS在从介质读取时仅检查元数据CRC,而不检查数据CRC;但是,您可以使用其中一个 UBIFS 挂载选项强制 CRC 检查数据 - 请参阅此处。
3. UBI文件系统的制作
3.1 UBI 常用指令
工具 | 作用 |
---|
ubinfo | 提供ubi设备和卷的信息 | ubiattach | 链接MTD设备到UBI并且创建相应的UBI设备 | ubidetach | ubiattach相反的操作,将MTD设备从UBI设备上去链接 | ubimkvol | 从UBI设备上创建UBI卷 | ubirmvol | 从UBI设备上删除UBI卷 | ubiblock | 管理UBI卷上的block | ubiupdatevol | 更新卷,例如OTA直接更新某个分区镜像 | ubicrc32 | 使用与ubi相同的基数计算文件的crc32 | ubinize | 制作UBI镜像 | ubiformat | 格式化空的Flash设备,擦除Flash,保存擦除计数,写入UBI镜像到Flash | mtdinfo | 报告从系统中找到的UBI设备的信息 |
3.2 制作ubi镜像
如何制作 UBIFS 映像?
制作闪存的映像,分为2步:
1. 创建一个 UBIFS 映像; 2. 创建 UBI 映像
因此,有2个实用工具:
工具 | 作用 |
---|
mkfs.ubifs | 创建 UBIFS 映像 | ubinize | 从UBIFS图像创建UBI图像 |
UBI和UBIFS映像取决于它们将要使用的闪存的参数。也就是说,在创建映像之前,必须了解闪存的以下特征:
MTD 分区大小; 闪存物理擦除块大小; 最小flash 输入/输出单元大小; 对于NAND flash - 子页面大小; 逻辑擦除块大小。 如果具有向后移植的 MTD 系统支持,则可以通过运行带有参数的 mtdinfo 工具来查找所有这些参数。
以下示例演示了如何为256MiB NAND flash chip, 具有 128KiB 物理擦除块(PEB) 2048 字节 NAND page 512 字节子page 创建 UBI/UBIFS 映像(这flash允许对同一 NAND 页面执行 4x512 字节的写入)。生成的映像将只有一个存储 UBIFS 文件系统的 UBI 卷。
$ mkfs.ubifs -q -r root-fs -m 2048 -e 129024 -c 2047 -o ubifs.img
$ ubinize -o ubi.img -m 2048 -p 128KiB -s 512 ubinize.cfg
其中包含:ubinize.cfg
$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=200MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
说明:
mkfs.ubifs
-r root-fs:告诉创建一个 UBIFS 映像,该映像将具有与本地目录相同的内容;
-m 2048:表示创建此 UBIFS 映像的闪存的最小输入/输出单元大小为 2048 字节(在本例中为 NAND 页);
-e 129024:创建此映像的 UBI 卷的逻辑擦除块大小;
-c 2047:在逻辑擦除块中指定最大文件系统大小;生成的FS可能会被置于高达约251MiB(129024乘以2047);
-p 128KiB:表示创建UBI映像的闪存芯片的物理擦除块大小为128KiB(128 * 1024字节);
ubinize
-s 512:表示闪存支持子页面,子页面大小为512字节; 将考虑到这一点,并将 VID 标头放在与 EC 标头相同的 NAND 页面上。
在示例中,该文件告诉创建一个 UBI 映像,该映像具有一个 ID 为 0 且名为"rootfs"的 200MiB 动态卷。配置文件还设置了"自动调整大小"卷标志,这意味着 UBI 将自动放大卷,以便在首次运行时具有最大可能的大小。有关什么是自动调整大小功能的详细信息,请参阅此处。由于我们指定了""选项,UBIFS 也将自动在第一个挂载上重新调整大小。因此,最终结果将是您有一个最大可能大小的卷,并且 UBIFS 跨越整个卷。ubinize.cfgubinize-c 2047mkfs.ubifs
请运行,以获取更多信息以及调整生成的图像的更多可能性。ubinize -hmkfs.ubifs -h
下面是 32MiB NOR 闪存的另一个示例,物理擦除块大小为 128KiB。
$ mkfs.ubifs -q -r root-fs -m 1 -e 130944 -c 255 -o ubifs.img
$ ubinize -o ubi.img -m 1 -p 128KiB ubinize.cfg
其中包含:ubinize.cfg
$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=30MiB
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
vol_flags=autoresize
还有一个例子是512MiB MLC NAND闪存,物理擦除块大小为128KiB,NAND页面大小为2048字节,不支持子页面写入。
$ mkfs.ubifs -q -r root-fs -m 2048 -e 126976 -c 4095 -o ubifs.img
$ ubinize -o ubi.img -m 2048 -p 128KiB ubinize.cfg
其中包含:ubinize.cfg
$ cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=450MiB
vol_type=dynamic
vol_name=rootfs
vol_alignment=1
vol_flags=autoresize
|