一、 UBIFS 简介
由IBM、nokia工程师Thomas Gleixner,Artem Bityutskiy等人于2006年发起,致力于开发性能卓越、扩展性高的FLASH专用文件系统,以解决当前嵌入式环境下以FLASH作为MTD设备使用时的技术瓶颈。
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. 配置linux内核
配置的时候选上
1)Device Drivers --->Memory Technology Device (MTD) support --->UBI - Unsorted block images --->Enable UBI
2)File systems --->Miscellaneous filesystems --->UBIFS file system support
这样我们的内核就支持UBIFS文件系统了
2. UBIFS工具
mtd-utils工具中提供了对UBIFS的支持,所以我们需要下载和编译这些工具,下载以下几个文件
1)下载(mtd-utils、zlib、lzo)源码
wget http://debian.mirror.inra.fr/deb ... 0080508.orig.tar.gz
wget http://www.zlib.net/zlib-1.2.3.tar.gz
wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz
2)编译安装zlib
tar xzvf zlib-1.2.3.tar.gz
cd zlib-1.2.3
make
make install
cd ..
3)编译安装lzo
tar xzvf lzo-2.03.tar.gz
cd lzo-2.03
make
make install
cd ..
4)编译mtd-utils
tar xzvf mtd-utils_20080508.orig.tar.gz
cd mtd-utils-20080508
make
mkfs.ubifs子目录下生成我们需要的mkfs.ubifs工具,通过这个工具我们能打包一个文件夹,生成UBIFS系统镜像
三、如何使用UBIFS
1) 制作根文件系统,比如我们的根文件目录为rootfs
2) 生成ubi烧写映像
mkfs.ubifs -r rootfs -m 512 -e 15872 -c 7976 -o ubifs.img
3) 通过UBOOT制作UBI分区
目前最新的UBOOT已经支持UBI分区,进入UBOOT命令行
分区表配置如下举例:
现在UBI分区已经创建完毕,我们可以通过tftp等手段把ubifs.img下载到RAM中, 0x30008000 为下载的地址, 0x2f8000 为 长度,文件系统烧写完成,修改uboot中的内核启动参数为
内核的下载没有什么变化,不在叙述,OK,工作到此结束,目前ubi文件已经移植到P1310上,工作正常。由于采用了压缩方式,UBI文件系统占用的空间比yaffs要小,而且避免了nand flash中OOB数据的操作,使得移植变得简单,值得推荐.
内核配置
使用UBIFS,首先需要在内核中使能MTD_UBI和UBIFS:
在MTD中使能UBI:
<*> Enable UBI
在FS中使能UBIFS:
<*> UBIFS file system support
工具支持
使用UBI,需要UBI的一些工具,如ubiattach ubimkvol等,这些工具都包含在教新版的mtd-utils中,我下载了mtd-utils-1.2.0.tar.bz2,其中就包含了ubi的工具,只需进行交叉编译即可。但是,交叉编译mtd-utils,需要zlib和lzo的支持,我分别下载了zlib-1.2.3.tar.gz和lzo-2.03.tar.gz,分别进行交叉编译并安装到交叉工具链中。
交叉编译zlib-1.2.3.tar.gz
解压后,进行配置编译即可,编译和安装命令:
CC=arm-vfp-linux-gnu-gcc ./configure --shared --prefix=/opt/nxp/gcc-4.3.2-glibc-2.7/arm-vfp-linux-gnu/
make
sudo make install
其中,因为使用普通用户,所以make install需要sudo操作。
交叉编译lzo-2.03.tar.gz
解压后进行配置和编译即可。
CC=arm-vfp-linux-gnu-gcc ./configure --host=arm-linux --prefix=/opt/nxp/gcc-4.3.2-glibc-2.7/arm-vfp-linux-gnu/
make
sudo make install
交叉编译mtd-utils-1.2.0
这需要修改Makefile文件。修改./Makefile,将其中的CROSS指定为:
CROSS=arm-vfp-linux-gnu-
CC := $(CROSS)gcc
修改./ubi-utils/Makefile文件,增加CROSS:
CROSS=arm-vfp-linux-gnu-
CC := $(CROSS)gcc
修改./ubi-utils/new-utils/Makefile文件,增加CROSS:
CROSS=arm-vfp-linux-gnu-
CC := $(CROSS)gcc
然后输入 make WITHOUT_XATTR=1 进行编译,编译完毕,可以得到flash_erase等工具。
再进入ubi-utils/目录,输入make,将会得到ubi的工具,将需要的工具复制添加到目标板的根文件系统中即可。我是放在rootfs/usr/bin目录下。
使用ubifs
我是通过NFS启动系统的,在系统启动后操作板子的NAND FLASH分区。
[root@zlg /]# more /proc/partitions
major minor #blocks name
31 0 1536 mtdblock0
31 1 256 mtdblock1
31 2 4096 mtdblock2
31 3 16384 mtdblock3
31 4 239616 mtdblock4
一共有5个mtd分区,我想将mtdblock4做为ubifs分区使用。
先擦除FLASH 分区mtd4:
[root@zlg /]# flash_eraseall /dev/mtd4
然后使用ubiattach:
[root@zlg /]# ubiattach /dev/ubi_ctrl -m 4
UBI: attaching mtd4 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB)
UBI: logical eraseblock size: 129024 bytes
UBI: smallest flash I/O unit: 2048
UBI: sub-page size: 512
UBI: VID header offset: 512 (aligned 512)
UBI: data offset: 2048
UBI: empty MTD device detected
UBI: create volume table (copy #1)
UBI: create volume table (copy #2)
UBI: attached mtd4 to ubi0
UBI: MTD device name: "smartarm3250-rootfs"
UBI: MTD device size: 234 MiB
UBI: number of good PEBs: 1870
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: 1848
UBI: total number of reserved PEBs: 22
UBI: number of PEBs reserved for bad PEB handling: 18
UBI: max/mean erase counter: 0/0
UBI: background thread "ubi_bgt0d" started, PID 609
UBI device number 0, total 1870 LEBs (241274880 bytes, 230.1 MiB), available 1848 LEBs (238436352 bytes, 227.4 MiB), LEB size 129024 bytes (126.0 KiB)
提示available 1848 LEBs (238436352 bytes, 227.4 MiB),238436352字节可用,但是ubi工具只识别KiB MiB GiB,并且只识别整数,所以需要进行换算。
238436352 bytes = 232848KiB
再使用ubimkvol在ubi设备上创建ubi卷:
[root@zlg /]# ubimkvol /dev/ubi0 -N rootfs -s 232848KiB
Volume ID 0, size 1848 LEBs (238436352 bytes, 227.4 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name "rootfs", alignment 1
提示创建ubi0成功,卷名为rootfs。
最后挂载:
[root@zlg /]# mount -t ubifs ubi0_0 /mnt 或者
mount -t ubifs ubi0:rootfs /mnt
UBIFS: default file-system created
UBIFS: background thread "ubifs_bgt0_0" started, PID 619
UBIFS: mounted UBI device 0, volume 0, name "rootfs"
UBIFS: file system size: 237017088 bytes (231462 KiB, 226 MiB, 1837 LEBs)
UBIFS: journal size: 11870208 bytes (11592 KiB, 11 MiB, 92 LEBs)
UBIFS: default compressor: LZO
UBIFS: media format 4, latest format 4
挂载上之后可用df查看:
[root@zlg /]# df
Filesystem 1k-blocks Used Available Use% Mounted on
rootfs 39994768 26688892 11274260 70% /
/dev/root 39994768 26688892 11274260 70% /
tmpfs 30636 24 30612 0% /dev
shm 30636 0 30636 0% /dev/shm
df: /mnt/rwfs: No such file or directory
ubi0:rootfs 217224 0 212160 0% /mnt
使用完毕可以卸载:
[root@zlg /]# umount /mnt/
UBIFS: un-mount UBI device 0, volume 0
可以通过NFS启动系统,挂载ubi分区后将根文件系统解压到ubi中,然后设置参数,使用ubifs作为根文件系统,设置参数:
setenv bootargs ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs console=ttyS0,115200 mem=64M
启动系统即可,如下是启动信息:
U-Boot 1.3.3 (May 5 2009 - 13:04:13)
DRAM: 64 MB
NAND: 256 MiB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
U-Boot$
U-Boot$ setenv bootargs ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs console=ttyS0,115200 mem=64M
U-Boot$ ru yboot
NAND read: device 0 offset 0x200000, size 0x1b5968
Reading data from 0x3b5800 -- 100% complete.
1792360 bytes read: OK
## Booting kernel from Legacy Image at 81000000 ...
Image Name: Linux-2.6.27.8
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1792296 Bytes = 1.7 MB
Load Address: 80008000
Entry Point: 80008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux..................................................................................... done, booting the kernel.
Linux version 2.6.27.8 ([email protected]) (gcc version 4.3.2 (crosstool-NG-1.3.1) ) #8 PREEMPT Fri Nov 6 05:59:13 CST 2009
CPU: ARM926EJ-S [41069264] revision 4 (ARMv5TEJ), cr=00053177
Machine: SmartARM3250 board with the LPC3250 Microcontroller
Memory policy: ECC disabled, Data cache writeback
CPU0: D VIVT write-back cache
CPU0: I cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets
CPU0: D cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs console=ttyS0,115200 mem=64M
PID hash table entries: 256 (order: 8, 1024 bytes)
Console: colour dummy device 80x30
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 61096KB available (3416K code, 230K data, 112K init)
Calibrating delay loop... 103.83 BogoMIPS (lpj=519168)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 288 bytes
NET: Registered protocol family 16
Invalid board descriptor!
LPC32XX DMA driver
SCSI subsystem initialized
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
yaffs Sep 5 2009 09:21:41 Installing.
msgmni has been set to 119
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
CLCD: ZHIYUAN LCD hardware, QVGA portrait display
Console: switching to colour frame buffer device 40x30
Serial: 8250/16550 driver4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x40090000 (irq = 9) is a 16550A
console [ttyS0] enabled
serial8250.0: ttyS1 at MMIO 0x40080000 (irq = 7) is a 16550A
serial8250.0: ttyS2 at MMIO 0x40088000 (irq = 8) is a 16550A
serial8250.0: ttyS3 at MMIO 0x40098000 (irq = 10) is a 16550A
lpc32xx_hsuart.0: ttyTX0 at MMIO 0x40014000 (irq = 26) is a lpc32xx_hsuart
lpc32xx_hsuart.0: ttyTX1 at MMIO 0x40018000 (irq = 25) is a lpc32xx_hsuart
lpc32xx_hsuart.0: ttyTX2 at MMIO 0x4001c000 (irq = 24) is a lpc32xx_hsuart
loop: module loaded
LPC32XX_mii_bus: probed
eth0: LPC32XX mac at 0x31060000 irq 29
eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=0:00, irq=-1)
Uniform Multi-Platform E-IDE driver
ide0 at 0xc4866020-0xc486602e,0xc486602e on irq 86
Driver 'sd' needs updating - please use bus_type methods
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 0 at 0x00000000
Bad eraseblock 1 at 0x00020000
Bad eraseblock 2 at 0x00040000
Bad eraseblock 152 at 0x01300000
Bad eraseblock 571 at 0x04760000
Bad eraseblock 1594 at 0x0c740000
Creating 5 MTD partitions on "lpc32xx_nand":
0x00000000-0x00180000 : "smartarm3250-boot"
0x00180000-0x001c0000 : "smartarm3250-ubt-prms"
0x00200000-0x00600000 : "smartarm3250-kernel"
0x00600000-0x01600000 : "smartarm3250-safefs"
0x01600000-0x10000000 : "smartarm3250-rootfs"
UBI: attaching mtd4 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB)
UBI: logical eraseblock size: 129024 bytes
UBI: smallest flash I/O unit: 2048
UBI: sub-page size: 512
UBI: VID header offset: 512 (aligned 512)
UBI: data offset: 2048
UBI: attached mtd4 to ubi0
UBI: MTD device name: "smartarm3250-rootfs"
UBI: MTD device size: 234 MiB
UBI: number of good PEBs: 1870
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: 1
UBI: available PEBs: 0
UBI: total number of reserved PEBs: 1870
UBI: number of PEBs reserved for bad PEB handling: 18
UBI: max/mean erase counter: 2/1
UBI: background thread "ubi_bgt0d" started, PID 262
at25 spi0.0: 32 KByte at25256a eeprom, pagesize 64
mice: PS/2 mouse device common for all mice
input: LPC32xx Touchscreen as /class/input/input0
rtc-lpc32xx rtc-lpc32xx: rtc core: registered rtc-lpc32xx as rtc0
i2c /dev entries driver
PNX4008-WDT: PNX4008 Watchdog Timer: heartbeat 19 sec
mmci-pl18x: DMA buffer(10000 bytes), P:0x839e0000, V:0xffc1a000
mmc0: MMCI rev 0 cfg 00 at 0x0000000020098000 irq 15,13
Advanced Linux Sound Architecture Driver Version 1.0.17.
ASoC version 0.13.2
UDA1380 Audio Codec 0.6<3>i2c-adapter i2c-4: Master timed out. stat = 0000, cntrl = 0000. Resetting master...
ALSA device list:
No soundcards found.
TCP cubic registered
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
ieee80211: 802.11 data/management/control stack, git-1.1.13
ieee80211: Copyright (C) 2004-2005 Intel Corporation
VFP support v0.3: implementor 41 architecture 1 part 10 variant 9 rev 1
rtc-lpc32xx rtc-lpc32xx: setting system clock to 2033-04-20 18:46:57 UTC (1997635617)
UBIFS: mounted UBI device 0, volume 0, name "rootfs"
UBIFS: file system size: 237017088 bytes (231462 KiB, 226 MiB, 1837 LEBs)
UBIFS: journal size: 11870208 bytes (11592 KiB, 11 MiB, 92 LEBs)
UBIFS: default compressor: LZO
UBIFS: media format 4, latest format 4
VFS: Mounted root (ubifs filesystem).
Freeing init memory: 112K
UBIFS: background thread "ubifs_bgt0_0" started, PID 304
init started: BusyBox v1.11.2 ()
starting pid 306, tty '': '/etc/rc.d/rcS'
Mounting /proc and /sys
Starting the hotplug events dispatcher udevd
Synthesizing initial hotplug events
Setting the hostname to zlg
Mounting filesystems
mount: mounting usbfs on /proc/bus/usb failed: No such file or directory
Running sysctl
Setting up networking on loopback device:
Setting up networking on eth0:
Adding static route for default gateway to 192.168.7.1:
Setting nameserver to 192.168.7.1 in /etc/resolv.conf:
Starting inetd:
Starting the port mapper:
Starting the ssh server:
starting pid 605, tty '': '-/bin/sh'
[root@zlg /]#
[root@zlg /]# ls
bin etc linuxrc proc sys usr
boot home mnt root tmp var
dev lib opt sbin ubifs
[root@zlg /]# df
Filesystem 1k-blocks Used Available Use% Mounted on
rootfs 217224 68612 143552 32% /
ubi0:rootfs 217224 68612 143552 32% /
tmpfs 30636 24 30612 0% /dev
shm 30636 0 30636 0% /dev/shm
rwfs 512 0 512 0% /mnt/rwfs
与YAFFS2测试对比:
从NAND FLASH中读取和复制一个文件,同样大小,分别使用YAFFS2和UBIFS系统的对比情况:
[root@nxp mp3]# ls -la bh_48128.mp3
-rw-r--r-- 1 user user 5689344 Feb 29 2008 bh_48128.mp3
文件大小差不多是5M多。
yaffs2的系统,测试时间是9秒钟:
[root@nxp mp3]# time cp bh_48128.mp3 bh_48128-2.mp3
real 0m 9.28s
user 0m 0.01s
sys 0m 9.26s
ubifs系统,测试时间差不多4秒多一点。
[root@zlg mp3]# time cp bh_48128.mp3 bh_48128-2.mp3
real 0m4.130s
user 0m0.000s
sys 0m2.810s
从这里就可以看出UBIFS速度远比YAFFS2快。
另外,UBIFS还采用了压缩,在PC上大约110MB的rootfs,固化到UBIFS分区后大约60多MB。
UBI和UBIFS的参考链接:
http://www.linux-mtd.infradead.org/doc/ubi.html
http://www.linux-mtd.infradead.org/doc/ubifs.html