UBIFS 简介
由IBM、nokia工程师Thomas Gleixner,Artem Bityutskiy等人于2006年发起,致力于开发性能卓越、扩展性高的FLASH专用文件系统,以解决当前嵌入式环境下以FLASH作为MTD设备使用时的技术瓶颈, 开发背景: FLASH特性: FLASH是一类电可擦出可编程存储体,在使用方式上与硬磁盘最大不同是: FLASH文件系统所必须的关键技术: 1. 由于FLASH的“先擦除后写”的特性决定,必须(或者说所被公认为)采用异地更新策略(out-of-place update)。相关问题讨论可参考: 2. 采用异地更新策略就必须(或者说所被公认为)采用日志文件系统来管理。 3. 采用日志文件系统就必须(或者说所被公认为)实现垃圾回收(garbage collection) 4. 由于FLASH的物理擦除块(Physical Erase Block)只有有限次有效擦除,所以必须(或者说所被公认为)采用“负载平衡”(我比较喜欢翻译为“损益均衡”——一个经济学术语)(Wear- Leveling)技术,即保证上的(几乎)所有 PEB的擦除次数趋向于均衡化,从而避免小部分PEB大大先于其他PEB而”坏“掉。 当前嵌入式FLASH解决方案多采用: 1. 无文件系统直接使用FLASH:缺点很明显 2. 采用传统文件系统,如ext2,ext3, FAT16/32, dos,Cramfs 等:这些文件系统本来是为传统的磁盘体开发的,他们无法高效的管理以FLASH作为介质的文件系统,特别是在FLASH的使用寿命上。于是出现了第3中方案。 3. 采用FTL/NFTL(flash 转换层/nand flash转换层)+ 传统文件系统:FTL的使用就是针对FLASH的特有属性,通过硬件的方式来实现日志管理、损益均衡等技术。但实践证明,由于各方面因素导致本方案有一定的局限性。 4. FLASH专用文件系统,如JFFS1/2,YAFFS等,他们从一定程度上缓解了flash使用上的技术瓶颈。但也仍然存在诸多问题:如内存消耗大,对 FLASH容量、文件系统大小、内容、访问模式等的线性依赖,损益均衡能力差活过渡损益。随作FLASH容量逐渐暴涨(我见到的资料已经有 64GFLASH已经实用化),JFFS,YAFFS几乎无法管理如此大的FLASH——虽然JFFS目前还在改进中,但前途不看好,一个很好的例子 JFFS的主要开发者大多倒向了UBIFS。:) UBI:一种类似于LVM的逻辑卷管理层。主要实现损益均衡,逻辑擦除块、卷管理,坏块管理等。 UBIFS:基于UBI的FLASH日志文件系统。 有关ubifs的详细介绍,请参考: http://www.linux-mtd.infradead.org/doc/ubi.html http://www.linux-mtd.infradead.org/doc/ubifs.html 使用UBIFS前的准备
1. 获取 ubifs: 2.6.22以后,ubifs活跃于git管理工程中 git://git.infradead.org/ubi-2.6.git 2.6.27以后,ubifs被整合进内核树中,用户只需下载最新内核即可获取ubifs支持。 2. 配置linux内核 (2.6.28 以上 kernel 已经包含 ubifs, 早期的kernel 还得去官网上找找,我的就是 2.6.28) 配置的时候选上 1)Device Drivers --->Memory Technology Device (MTD) support --->UBI - Unsorted block images --->Enable UBI
2)File systems --->Miscellaneous filesystems --->UBIFS file system support
这样我们的内核就支持UBIFS文件系统了 3. UBIFS工具 mtd-utils工具中提供了对UBIFS的支持,所以我们需要下载和编译这些工具,下载以下几个文件 1)下载mtd-utils wget
http://debian.mirror.inra.fr/debian/pool/main/m/mtd-utils/mtd-utils_20080508.orig.tar.gz tar xzvf mtd-utils_20080508.orig.tar.gz cd mtd-utils-20080508
2)编译mtd-utils (主要是修改工具链) 修改Makefile文件: #CROSS=arm-linux-
修改为 CROSS=arm-marvell-linux-gnueabi- BUILDDIR := $(CROSS:-=) 修改为 BUILDDIR := .
修改ubi-utils/Makefile文件:
添加 CROSS=arm-marvell-linux-gnueabi- 修改 ubi-utils/new-utils/Makefile文件: 添加 CROSS=arm-marvell-linux-gnueabi-
make WITHOUT_XATTR=1
3) ubi-utils子目录下生成我们需要的ubiattach、ubimkvol等文件(请确保是交叉编译所得)
mkfs.ubifs子目录下生成我们需要的mkfs.ubifs工具,通过这个工具我们能打包一个文件夹,生成UBIFS系统镜像,
我是使用 nfs 启动, 直接解压文件到 flash 上,所以并没有使用 mkfs.ubifs工具.
另外网络上很多文中提到 zlib、lzo 这两个库,但是我并没有使用到。
如何使用UBIFS
1. 使用nfs启动系统, 首先建立设备节点: 以下操作可以用mdev –s 生成 mknod /dev/ubi_ctrl c 10 58 mknod /dev/ubi0 c 250 0
2、 执行以下命令挂载ubifs: 1.flash_eraseall /dev/mtd8 #擦出分区 2.ubiattach /dev/ubi_ctrl -m 8 –O #建立关联 3.ubimkvol /dev/ubi0 -N rootfs -s 30MiB ubimkvol创建容量, -s 是设置大小 , 此步的作用在于mtd8中没有烧录数据之前需要通过此步才可以挂载文件系统到挂载点下。由于此处用的是nfs和tar组合烧录,所以需要先挂载ubi设备文件到挂载点,才能进行解压,因此在挂载之前需要这一步。如果已经将镜像焼写到了相应块设备中,则可以免去这一句。
关于tar焼写文件的原理:
将任何一个文件夹下的目录进行tar打包之后,它们都是以二进制的文件存在,是脱离于文件系统的,将他们解压到某一个目录时,此目录的文件系统格式,就决定了它们在设备上的摆放方式,也就决定了它们在设备上所处的文件系统类型。如果tar了所有rootfs所具备的资源,并将他们tar vf –C 到ubi文件系统类型的目录下,那么它们无异与被写入了目录所挂载的相应的块设备,并以ubi文件系统的格式存在,那么和用nand write 或 flashcp 将用mkfs.ubifs
flashcp –v /opt/mtc/xxxx.ubifs /dev/mtd8
制作出来的的rootfs镜像没有区别,只是在生产时,有一定的限制,所以最好还是用nand write 提前焼写到nand flash在内核中对其的所分的相应分区地址空间内。如下:
Creating 6 MTD partitions on \
0x000000000000-0x000010000000 : \0x000000000000-0x000000800000 : \0x000000800000-0x000001000000 : \0x000001000000-0x000002000000 : \0x000002000000-0x000004000000 : \0x000004000000-0x000020000000 : \
4.mount -t ubifs ubi0_0 /mnt 或者mount -t ubifs ubi0:rootfs /mnt uboot 如何支持 UBIFS 为根文件系统启动
setenv bootargs console=ttyS0,115200 ubi.mtd=4 root=ubi0_0 rootfstype=ubifs
ip=192.168.1.101:192.168.1.100::255.255.255.0::usb0:on
下面附上一个我自己通过 nfs 启动以后, 烧写 kernel 和文件系统的脚本。 #!/bin/sh
TestResult() {
if [ $? -ne 0 ]; then
echo \ exit 1 else
echo \ echo \fi }
#Erase the flash partition
echo \Erase the flash partitin----------------\/mtd-utils/usr/sbin/flash_eraseall /dev/mtd3 /mtd-utils/usr/sbin/flash_eraseall /dev/mtd4 echo \Install kernel and software to flash----------------\
/bin/dd if=/zImage of=/dev/mtdblock3
mkdir -p /mountpoint
mknod /dev/ubi_ctrl c 10 58 mknod /dev/ubi0 c 250 0
/mtd-utils/ubi/ubiattach /dev/ubi_ctrl -m 8 –O 2048 TestResult \
/mtd-utils/ubi/ubimkvol /dev/ubi0 -N rootfs -s 30MiB
TestResult \/bin/mount -t ubifs ubi0_0 /mountpoint
TestResult \echo \tar xf /FSSoftware.tar -C /mountpoint sync
/bin/umount /mountpoint
echo
\echo \ Please set uboot environment: \
echo \rootfstype=ubifs
ip=192.168.1.101:192.168.1.100::255.255.255.0::usb0:on\echo
\exit 0 另外 ubifs 是一个异步的文件系统, 所以为了掉电的时候数据能保存完整, 最好使用 -o sync 挂载文件系统。
具体操作如下
U-Boot 1.3.1 (Sep 1 2012 - 00:07:37) - stm24_0057 DRAM: 256 MiB NOR: 4 MiB NAND: Bad block table found at page 262080, version 0x01 Bad block table found at page 262016, version 0x01 512 MiB In: serial Out: serial