內核移植和文件系統製作(4):UBIFS根文件系統製作總結

UBIFS文件系統簡介: 

無排序區塊圖像文件系統(UnsortedBlock Image File System, UBIFS)是用於固態硬盤存儲設備上,並與LogFS相互競爭,作爲JFFS2的後繼文件系統之一。真正開始開發於2007年,並於2008年10月第一次加入穩定版本於Linux核心2.6.27版。UBIFS最早在2006年由IBMNokia的工程師Thomas Gleixner,ArtemBityutskiy所設計,專門爲了解決MTD(MemoryTechnology Device)設備所遇到的瓶頸。由於Nand Flash容量的暴漲,YAFFS等皆無法再去控制Nand Flash的空間。UBIFS通過子系統UBI處理與MTD device之間的動作。JFFS2一樣,UBIFS建構於MTD device之上,因而與一般的block device不兼容。JFFS2運行在MTD設備之上,而UBIFS則只能工作於UBIvolume之上。也可以說,UBIFS涉及了三個子系統:

1.      MTD 子系統, 提供對flash芯片的訪問接口,MTD子系統提供了MTD device的概念,比如/dev/mtdx,MTD可以認爲是raw flash

2.      UBIsubsystem,爲flash device提供了wear-leveling和 volume management功能; UBI工作在MTD設備之上,提供了UBI volume;UBI是MTD設備的高層次表示,對上層屏蔽了一些MTD不得不處理的問題,比如wearing以及壞塊管理

3.      UBIFS文件系統,工作於UBI之上,必須在Device Drivers中選擇支持MTD


以下是UBIFS的一些特點:

Ø     可擴展性:UBIFS對flash 尺寸有着很好的擴展性; 也就是說mount時間,內存消耗以及I/O速度都不依賴與flash 尺寸(對於內存消耗並不是完全準確的,但是依賴性非常的低);UBIFS可以很好的適應GB flashes;  當然UBI本身還有擴展性的問題,無論如何 UBI/UBIFS都比JFFS2的可擴展性好,此外如果UBI成爲瓶頸,還可以通過升級UBI而不需改變UBIFS

Ø     快速mount:不像JFFS2,UBIFS在mount階段不需要掃描整個文件系統,UBIFS mount介質的時間只是毫秒級,時間不依賴與flash的尺寸;然而UBI的初始化時間是依賴flash的尺寸的,因此必須把這個時間考慮在內

Ø     write-back支持:回寫或者叫延遲寫更準確些吧,同JFFS2的write-through(立即寫入內存)相比可以顯著的提高文件系統的吞吐量。

Ø     異常unmount適應度:UBIFS是一個日誌文件系統可以容忍突然掉電以及unclean重啓; UBIFS 通過replay 日誌來恢復uncleanunmount,在這種情況下replay會消耗一些時間,因此mount時間會稍微增加,但是replay過程並不會掃描整個flash介質,所以UBIFS的mount時間大概在幾分之一秒。

Ø     快速I/O - 即使我們disablewrite-back(可以在unmount時使用-o syncmount選項), UBIFS的性能仍然接近JFFS2;記住,JFFS2的同步I/O是非常驚人的,因爲JFFS2不需要在flash上維護indexing data結構, 所以就沒有因此而帶來的負擔; 而UBIFS恰恰是有index數據的。 UBIFS之所以夠快是因爲UBIFS提交日誌的方式:不是把數據從一個地方移動到另外一個位置,而只是把數據的地址加到文件系統的index,然後選擇不同的eraseblock作爲新的日誌塊,此外還有multi-headed日誌方式等技巧。

Ø     on-the_flightcompression - 存儲在flash介質上的數據是壓縮的;同時也可以靈活的針對單個文件來打開關閉壓縮; 例如,可能需要針對某個特定的文件打開壓縮,或者可能缺省方式下支持壓縮,但是對多媒體文件則關閉壓縮。

Ø     可恢復性 - UBIFS可以從index破壞後恢復; UBIFS中的每一片信息都有一個header來描述,因此可以通過掃描這個flash介質來重構文件系統,這點和JFFS2非常類似;想像一下,如果你擦出了FAT文件系統的FAT表,那麼對於FAT FS是致命的錯誤,但是如果擦除UBIFS的index,你人然可以重構文件系統,當然這需要一個特定的用戶空間程序來做這個恢復

Ø     完整性 - UBIFS通過寫checksum到flash 介質上來保證數據的完整性,UBIFS不會無視損壞文件數據或meta-data;缺省的情況,UBIFS僅僅檢查meta-data的CRC,但是你可以通過mount選項,強制進行data CRC的檢查


UBIFS文件系統製作過程:

1,添加內核支持(linux-3.8.0):

  Device Drivers  --->    

<*> Memory Technology Device (MTD) support  --->    

 <*>   Enable UBI - Unsorted block images  --->   

--- Enable UBI - Unsorted block images 

(4096) UBI wear-leveling threshold  

(1)   Maximum expected bad eraseblock count per 1024 eraseblocks

[ ]   UBI Fastmap (Experimental feature)  

< >   MTD devices emulation driver (gluebi)  


  File systems  --->  

 [*] Miscellaneous filesystems  --->   

<*>   UBIFS file system support 

[*]     Advanced compression options 

[*]       LZO compression support

[*]       ZLIB compression support 


make編譯即可


2,製作文件UBIFS文件系統鏡像

mkfs.ubifs工具製作的文件系統映像,在uboot中燒錄這種映像文件的方式過於複雜,既要使uboot支持nandflash分區,又要在uboot中激活這個分區,並通過ubi write命令燒錄這個映像。爲便於移植,需要用到 mkfs.ubifs,ubinize工具,它的作用是將mkfs.ubifs製作的映像轉換爲可以直接用nand write命令燒錄的映像文件。

由於製作mkfs.jffs2和mkfs.ubifs工具,會同時生成ubinize工具,自己就是按照腳本製作的工具和生成UBIFS文件系統鏡像。

(1)製作mkfs.jffs2mkfs.ubifs工具的鏈接:http://blog.csdn.net/fulinus/article/details/8860836

(2)生成UBIFS的腳本:


注意兩點:

mkfs.ubifs工具需要明確的參數:

m:頁大小,如上:2K

x: 鏡像壓縮格式,可選 LZO

e:邏輯可擦除塊大小

c: 最多邏輯可擦除數目

r(或d):指定根文件目錄樹

o:指定生產文件名


ubinize工具需要明確的參數:

需要指定一個配置文件,格式如下:

[ubifs-volume]
mode=ubi
image=filename //文件名稱,即mkfs.ubifs文件製作生產文件
vol_id=0
vol_size= filesize //文件大小,按實際情況來定
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
vol_alignment=1

m: 頁大小,2k

p: 物理塊擦除大小

s:一般和頁大小一樣 2k

v:頭部大小,一般是512

o: 指定輸出文件


mkfs.ubifs和ubinize用法參考鏈接:

http://wenku.baidu.com/link?url=ZjS_qifTxWr68prdj780aT6yFp0rD8IbZGFvbT0ASwUhZbvdQBBzyIGTp_d5bbJx5IAb4TJX4CDmdUJ26mRwn2hij7G58X-WHPZVYCpR1MG


UBIFS文件系統介紹:

http://wenku.baidu.com/view/eebeacd9a58da0116c174991.html




製作腳本:

[zhouguangfeng@localhost ubifs]$ vim build_ubifs.sh 


#!/bin/sh

CPU=zhou
rootfs_dir=../rootfs //指定根文件目錄,根據根文件目錄樹而定
partition_sizeM=40
image_name=rootfs_${CPU}.ubifs


if [ ! -d $rootfs_dir ] ; then
    echo "Miss rootfs source code tree \"$rootfs_dir\" exit..."
    exit;
fi


#Default setting by UBIFS
sub_page_size=512
vid_head_offset=512


#-m, minimum I/O unit size, it's 2K(the Page size) on K9F2G08, refer to "UBI: smallest flash I/O unit:    2048" 
page_size_in_bytes=2048
#echo "Page size [$page_size_in_bytes] bytes."


#It's 64 pages per block on K9F2G08
pages_per_block=64
block_size_in_bytes=`expr $page_size_in_bytes \* $pages_per_block`
#echo "[$pages_per_block] pages per block and [$block_size_in_bytes] bytes"


#It's 2048 blocks on K9F2G08
blocks_per_device=2048
#echo "Blocks per device  [$blocks_per_device]"


#-e, logical erase block size, fixed on K9F2G08, refer to u-boot information "UBI: logical eraseblock size:  129024 bytes"
# logical erase block size is physical erase block size minus 1 page for UBI
logical_pages_per_block=`expr $pages_per_block - 1`
logical_erase_block_size=`expr $page_size_in_bytes \* $logical_pages_per_block`
#echo "Logical erase block size:  [$logical_erase_block_size] bytes."





#The rootfs partition size in bytes
partition_size_in_bytes=`expr $partition_sizeM \* 1024 \* 1024`
partition_physical_blocks=`expr $partition_size_in_bytes / $block_size_in_bytes`
#echo "Partition size [$partition_size_in_bytes] bytes and [$partition_physical_blocks] blocks."


#Logical blocks on a partition = physical blocks on a partitiion - reserved for wear level 
patition_logical_blocks=`expr $partition_physical_blocks - $wear_level_reserved_blocks`
#echo "Logical blocks in a partition [$patition_logical_blocks]"


#File-system volume = Logical blocks in a partition * Logical erase block size
fs_vol_size=`expr $patition_logical_blocks \* $logical_erase_block_size`
#echo "File-system volume [$fs_vol_size] bytes."


config_file=rootfs_ubinize.cfg
image_tmp=ubifs-${CPU}.img


set -x

echo ""
echo "Generating $image_name file by mkfs.ubifs..."
/usr/bin/mkfs.ubifs -x lzo -m $page_size_in_bytes -e $logical_erase_block_size -c $patition_logical_blocks -r
$rootfs_dir -o $image_tmp
set +x


echo
echo "Generating configuration file..."
echo "[ubifs-volume]" > $config_file
echo "mode=ubi" >> $config_file
echo "image=$image_tmp" >> $config_file
echo "vol_id=0" >> $config_file
echo "vol_size=$fs_vol_size" >> $config_file
echo "vol_type=dynamic" >> $config_file
echo "vol_name=rootfs" >> $config_file
echo "vol_flags=autoresize" >> $config_file
echo "vol_alignment=1" >> $config_file
echo


set -x
/usr/bin/ubinize -o $image_name -m $page_size_in_bytes -p $block_size_in_bytes -s $sub_page_size  -O    $vid_head_offset
$config_file

rm -f $image_tmp $config_file
cp $image_name /tftp

set +x

[zhouguangfeng@localhost ubifs]$ sh build_ubifs.sh 

[zhouguangfeng@localhost ubifs]$ ls
build_ubifs.sh  rootfs_zhou.ubifs
[zhouguangfeng@localhost ubifs]$ OK!


使用的linux服務器已經開啓tftp,ip爲192.168.1.3,最後腳本直接將鏡像文件拷貝到/tftp目錄下,並在uboot下設置serverip爲192.168.1.3。


3,在uboot添加對UBIFS的支持

nandflash分區如下:

Creating 9 MTDpartitions on "NAND":

0x000000000000-0x000000100000: "mtdblock0_u-Boot 1MB "

0x000000100000-0x000001000000 : "mtdbolck1_kernel 15MB"

0x000001000000-0x000002400000: "mtdbolck2_ramdisk 20MB"

0x000002400000-0x000003800000: "mtdblock3_cramfs 20MB"

0x000003800000-0x000006000000: "mtdblock4_jffs2 40MB"

0x000006000000-0x000008800000: "mtdblock5_yaffs2 40MB"

0x000008800000-0x00000b000000: "mtdblock6_ubifs 40MB"

0x00000b000000-0x00000d800000: "mtdblock7_apps 40MB"

0x00000d800000-0x000010000000: "mtdblock8_data 40MB"

其中kernel和UBIFS鏡像文件系統燒寫的地址一定要與分區對應,分區mtdbolck1放置內核分區mtdblock6放置UBIFS,偏移分別爲100000和8800000


[ s3c2440@zhou ]# set serverip 192.168.1.3

[ s3c2440@zhou ]# set bubifs 'tftp 30008000 rootfs_zhou.ubifs;nand erase 8800000 2800000;nand write 30008000 8800000 800000'

[ s3c2440@zhou ]# set bootargs_ubifs 'console=ttyS0,115200 mem=64Mubi.mtd=6 root=ubi0:rootfs rootwait rootfstype=ubifs rw'

[ s3c2440@zhou ]# set bootargs  'console=ttyS0,115200 mem=64Mubi.mtd=6 root=ubi0:rootfs rootwait rootfstype=ubifs rw'

[ s3c2440@zhou ]# set bootcmd_rootfs 'nand read 30008000 100000 800000;bootm 30008000'

[ s3c2440@zhou ]# set bootcmd 'run bootcmd_rootfs'

[ s3c2440@zhou ]# save                  
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x60000 -- 100% complete.
Writing to Nand... done
[ s3c2440@zhou ]# pri
cpu=s3c2440
bbl=tftp 30008000 u-boot-$cpu.bin;nand erase 0 100000;nand write 30008000 0 $filesize
norbbl=erase bank 1; tftp 30008000 u-boot-$cpu.bin;cp.b 30008000 0 $filesize
blx=tftp 30008000 linuxrom-$cpu.bin;nand erase 100000 F00000;nand write 30008000 100000 $filesize
bcramfs=tftp 30800000 cramfs-$cpu.rootfs;nand erase 2400000 1400000;nand write 30800000 2400000 $filesize
tb=tftp 30008000 linuxrom-$cpu.bin;bootm 30008000 
bootargs_initamfs=console=ttyS0,115200 mem=64M rw loglevel=7
bootargs_ramdisk=console=ttyS0,115200 root=/dev/ram0 initrd=0x30800000,16M init=/linuxrc mem=64M rw loglevel=7
bootargs_cramfs=console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=cramfs init=/linuxrc mem=64M noinitrd        loglevel=7
bootargs_jffs2=console=ttyS0,115200 root=/dev/mtdblock4 rootfstype=jffs2 init=/linuxrc mem=64M rw noinitrd         loglevel=7
mtdparts=mtdparts=nand0:1m(uboot),15m(kernel),20m(ramdisk),20m(cramfs),20m(jffs2),20m(yaffs2),20m(ubifs),-(users)
baudrate=115200
ethaddr=08:08:11:18:12:27
ethact=dm9000
bootdelay=1
bkr=tftp 30008000 linuxrom-s3c2440_zhou.bin;nand erase 100000 800000;nand write 30008000 100000 800000
bootargs_ubifs=console=ttyS0,115200 mem=64M ubi.mtd=6 root=ubi0:rootfs rootwait rootfstype=ubifs rw
bootcmd_rootfs=nand read 30008000 100000 800000;bootm 30008000
bubifs=tftp 30008000 rootfs_zhou.ubifs;nand erase 8800000 2800000;nand write 30008000 8800000 800000
brdfs=tftp 30008000 ramdisk_zhou.gz;nand erase 1000000 1400000;nand write 30008000 1000000 800000
bootcmd_ramdisk=nand read 30008000 100000 800000;nand read 30800000 1000000 800000;bootm 30008000
bootcmd=run bootcmd_rootfs
bootargs_nfs=noinitrd console=ttyS0,115200 init=/linuxrc mem=64M loglevel=7 root=/dev/nfs rw nfsroot=192.168.1.3:/opt/ ip=192.168.1.224:192.168.1.3:192.168.1.1:255.255.255.0:localhost.com:eth0:off
filesize=2F8910
fileaddr=30008000
gatewayip=192.168.1.1
netmask=255.255.255.0
serverip=192.168.1.3
bootargs=console=ttyS0,115200 mem=64M ubi.mtd=6 root=ubi0:rootfs rootwait rootfstype=ubifs rw
ipaddr=192.168.1.220
stdin=serial
stdout=serial
stderr=serial


Environment size: 2076/131068 bytes

[ s3c2440@zhou ]# run bkr
dm9000 i/o: 0x20000300, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.3; our IP address is 192.168.1.220
Filename 'linuxrom-s3c2440_zhou.bin'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         ###############################
done
Bytes transferred = 3304240 (326b30 hex)


NAND erase: device 0 offset 0x100000, size 0x800000
Erasing at 0x8e0000 -- 100% complete.
OK


NAND write: device 0 offset 0x100000, size 0x800000
 8388608 bytes written: OK
[ s3c2440@zhou ]# run bubifs 
dm9000 i/o: 0x20000300, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 08:08:11:18:12:27
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.3; our IP address is 192.168.1.220
Filename 'rootfs_zhou.ubifs'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         ######################################
done
Bytes transferred = 3407872 (340000 hex)


NAND erase: device 0 offset 0x8800000, size 0x2800000
Skipping bad block at  0x09c60000                                          
Erasing at 0xafe0000 -- 100% complete.
OK


NAND write: device 0 offset 0x8800000, size 0x800000
 8388608 bytes written: OK
[ s3c2440@zhou ]#    boot



NAND read: device 0 offset 0x100000, size 0x800000
 8388608 bytes read: OK
## Booting kernel from Legacy Image at 30008000 ...
   Image Name:   Linux Kernel
   Created:      2014-08-22  11:27:56 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3304176 Bytes = 3.2 MiB
   Load Address: 30008000
   Entry Point:  30008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK
OK
OS entry point: 30008040
Image entry point=30008040


Starting kernel ...

......

UBI: attaching mtd6 to ubi0
UBI: scanning is finished
UBI: attached mtd6 (name "mtdblock6_ubifs 40MB", size 40 MiB) to ubi0
UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
UBI: VID header offset: 512 (aligned 512), data offset: 2048
UBI: good PEBs: 319, bad PEBs: 1, corrupted PEBs: 0
UBI: user volume: 1, internal volumes: 1, max. volumes count: 128
UBI: max/mean erase counter: 2/0, WL threshold: 4096, image sequence number: 1940096911
UBI: available PEBs: 0, total reserved PEBs: 319, PEBs reserved for bad PEB handling: 1
UBI: background thread "ubi_bgt0d" started, PID 501
s3c-rtc s3c2410-rtc: setting system clock to 2014-08-22 20:58:16 UTC (1408741096)
ALSA device list:
  No soundcards found.
UBIFS: background thread "ubifs_bgt0_0" started, PID 503
usb 1-1: new full-speed USB device number 2 using s3c2410-ohci
UBIFS: mounted UBI device 0, volume 0, name "rootfs"(null)
UBIFS: LEB size: 129024 bytes (126 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes
UBIFS: FS size: 37416960 bytes (35 MiB, 290 LEBs), journal size 5160960 bytes (4 MiB, 40 LEBs)
UBIFS: reserved for root: 0 bytes (0 KiB)
UBIFS: media format: w4/r0 (latest is w4/r0), UUID 8F308069-E353-4739-8E3A-5CB1967E7A24, small LPT model
VFS: Mounted root (ubifs filesystem) on device 0:11.
devtmpfs: mounted
Freeing init memory: 156K
usb 1-1: New USB device found, idVendor=05e3, idProduct=0606
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1: Product: USB Hub 2.0
hub 1-1:1.0: USB hub found
hub 1-1:1.0: 4 ports detected
dm9000 dm9000 eth0: link down
dm9000 dm9000 eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1



Copyright (C) 2014 zhouguangfeng<[email protected]>
root login: root
Password: 
[root@root /]# OK




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章