UBI 文件系统

简介

UBIFS 文件系统代表 UBI 文件系统。UBI 代表 “未排序块镜像”。UBIFS 是一种闪存文件系统,这意味着它被设计为与闪存设备一起工作。重要的是要理解,UBIFS 与 Linux 中任何传统的 文件系统 (例如 Ext2、XFS、JFS 等) 完全不同。UBIFS 代表一类单独的文件系统,它们与 MTD 设备一起工作,而不是块设备。此类的另一个 Linux 文件系统是 JFFS2。

为了更清楚地说明,这里有一个 MTD 设备和块设备的小比较。

1 MTD 设备代表闪存设备,它们由擦除块组成,擦除块的大小

相当大,通常约为 128KiB。块设备由小块组成,通常为 512 字节。

2 MTD 设备支持 3 个主要操作 - 从擦除块内的某个偏移量读取、

写入到擦除块内的某个偏移量,以及擦除整个擦除块。块设备支持 2 个主要操作 - 读取整个块和写入整个块。

3 整个擦除块必须被擦除,然后才能重新写入其内容。块可以

被直接重新写入。

4 擦除块在经过一定次数的擦除周期后会磨损 -

对于 SLC NAND 和 NOR 闪存,通常为 100K-1G,对于 MLC NAND 闪存,通常为 1K-10K。块不具有磨损属性。

5 擦除块可能会损坏(仅在 NAND 闪存上),软件应

处理这种情况。硬盘驱动器上的块通常不会损坏,因为硬件具有替换坏块的机制,至少在现代 LBA 磁盘中是这样。

很明显,为什么 UBIFS 与传统文件系统非常不同。

UBIFS 在 UBI 之上工作。UBI 是一个单独的软件层,可以在 drivers/mtd/ubi 中找到。UBI 基本上是一个卷管理和磨损均衡层。它提供了所谓的 UBI 卷,这是一个比 MTD 设备更高层次的抽象。UBI 设备的编程模型与 MTD 设备非常相似 - 它们仍然由大的擦除块组成,它们具有读/写/擦除操作,但 UBI 设备没有诸如磨损和坏块之类的限制(上述列表中的第 4 项和第 5 项)。

从某种意义上说,UBIFS 是下一代 JFFS2 文件系统,但它与 JFFS2 非常不同且不兼容。以下是主要区别。

  • JFFS2 在 MTD 设备之上工作,UBIFS 依赖于 UBI 并在 UBI 卷之上工作。

  • JFFS2 没有介质索引,必须在挂载时构建它,这需要完整的介质扫描。UBIFS 将 FS 索引信息维护在闪存介质上,不需要完整的介质扫描,因此它的挂载速度比 JFFS2 快得多。

  • JFFS2 是一个写透文件系统,而 UBIFS 支持写回,这使得 UBIFS 在写入时速度快得多。

与 JFFS2 类似,UBIFS 支持动态压缩,这使得可以将相当多的数据放入闪存中。

与 JFFS2 类似,UBIFS 可以容忍不干净的重启和断电。它不需要像 fsck.ext2 这样的东西。UBIFS 会自动重播其日志并从崩溃中恢复,从而确保闪存上的数据结构一致。

UBIFS 以对数方式缩放(它使用的大多数数据结构都是树),因此挂载时间和内存消耗不会像 JFFS2 那样线性地依赖于闪存大小。这是因为 UBIFS 将 FS 索引维护在闪存介质上。但是,UBIFS 依赖于 UBI,后者线性缩放。因此,总的来说,UBI/UBIFS 堆栈线性缩放。尽管如此,UBI/UBIFS 的缩放效果明显优于 JFFS2。

UBIFS 的作者认为,有可能开发 UBI2,它也可以以对数方式缩放。UBI2 将支持与 UBI 相同的 API,但它将与 UBI 二进制不兼容。因此,UBIFS 不需要更改即可使用 UBI2

挂载选项

(*) == 默认。

bulk_read

一次读取更多内容,以利用顺序读取速度更快的闪存介质

no_bulk_read (*)

不批量读取

no_chk_data_crc (*)

跳过对数据节点上的 CRC 的检查,以提高读取性能。仅当闪存介质高度可靠时才使用此选项。此选项的效果是,文件的内容损坏可能会被忽略。

chk_data_crc

不跳过对数据节点上的 CRC 的检查

compr=none

覆盖默认压缩器并将其设置为 “none”

compr=lzo

覆盖默认压缩器并将其设置为 “lzo”

compr=zlib

覆盖默认压缩器并将其设置为 “zlib”

auth_key=

指定用于验证文件系统的密钥。传递此选项会使身份验证成为强制性的。传递的密钥必须存在于内核密钥环中,并且必须是“logon”类型

auth_hash_name=

用于身份验证的哈希算法。用于哈希和创建 HMAC。典型值包括 “sha256” 或 “sha512”

快速使用说明

要挂载的 UBI 卷使用 “ubiX_Y” 或 “ubiX:NAME” 语法指定,其中 “X” 是 UBI 设备号,“Y” 是 UBI 卷号,“NAME” 是 UBI 卷名。

将 UBI 设备 0 上的卷 0 挂载到 /mnt/ubifs

$ mount -t ubifs ubi0_0 /mnt/ubifs

将 UBI 设备 0 的 “rootfs” 卷挂载到 /mnt/ubifs(“rootfs” 是卷名)

$ mount -t ubifs ubi0:rootfs /mnt/ubifs

以下是将 mtd0 附加到 UBI 并挂载卷 “rootfs” 的内核启动参数示例:ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs

参考文献

MTD 网站上的 UBIFS 文档和 FAQ/HOWTO