ubi实际使用
ubifs號稱性能比yaffs2 好,同時(shí)壓縮可讀寫,文件系統(tǒng)image體較小同時(shí)可寫。
1. uboot使能對UBIFS的支持
#define CONFIG_CMD_NAND
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_RBTREE
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_LZO
注:需要燒寫mkfs.ubifs結(jié)果時(shí)候需要打開,ubinize處理過的鏡像不需要打開ubi專有配置。
2. Kernel使能對UBIFS的支持
?Enabling UBI support on MTD devices.
Device Drivers --->
Memory Technology Device (MTD) support --->
Enable UBI - Unsorted block images --->
?Enabling UBIFS file-system support
File systems --->
Miscellaneous filesystems --->
UBIFS file system support
3. 下載和編譯MTD Utilities
3.1 下載 MTD Utilites
通過 git://git.infradead.org/mtd-utils.git 下載最新的 MTD-Utils 源代碼。
下載 3 個編譯所需的依賴庫
Zlib: http://zlib.net/
Lzo: http://www.oberhumer.com/opensource/lzo/download/
e2fsprogs: http://e2fsprogs.sourceforge.net/
在用戶目錄下建立/mtd, /mtd/install 目錄,將以上 4 個 source code 包拷貝到/mtd下,安裝如下步驟先編譯依賴包:
zlib
host$ tar xvf zlib-1.2.5.tar.gz
host$ cd zlib-1.2.5/
host$ ./configure --prefix=~/mtd/install
host$ make
host$ make install
host$ cd ..
lzo
host$ tar xvf lzo-2.06.tar.gz
host$ cd lzo-2.06/
host$ ./configure --build=i686-pc-linux --prefix=~/mtd/install
host$ make
host$ make install
host$ cd ..
e2fsprogs
host$ tar xvf e2fsprogs-1.42.tar.gz
host$ cd e2fsprogs-1.42/
host$ ./configure --build=i686-pc-linux --prefix=~/mtd/install
host$ make
host$ make install
host$ cd lib/uuid/
host$ make install
host$ cd ../../../
3.2 編譯 MTD Utilites:
在編譯 mtd-utils 之前,先修改 makfile 文件:
host$ vi Makefile
PREFIX = ~/mtd/install
ZLIBCPPFLAGS = -I$(PREFIX)/include
LZOCPPFLAGS = -I$(PREFIX)/include
ZLIBLDFLAGS = -L$(PREFIX)/lib
LZOLDFLAGS = -L$(PREFIX)/lib
LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
CFLAGS ?= -O2 -g $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)
host$ vi common.mk
#PREFIX=/usr
然后依照如下指令編譯:
host$ WITHOUT_XATTR=1 make
host$ make install DESTDIR=~/mtd/install
host$ cd ..
制作 ubi 文件系統(tǒng)所用的工具在如下目錄下: ~/mtd/install/home/<username>/mtd/install/sbin/mkfs.ubifs ~/mtd/install/home/<username>/mtd/install/sbin/ubinize
注:可直接采用系統(tǒng)自帶的mkfs.ubifs和ubinize工具,若不存在可apt-get安裝。
4. ubifs制作
(1) mkfs.ubifs
制作UBIFS image
mkfs.ubifs -r system -m 2048 -e 126976 -c 1057 -x zlib -o system.ubifs
mkfs.ubifs -r rootfs -o rootfs.img -F -m 2048 -e 124KiB -c 40
-r:待制作的文件系統(tǒng)目錄。
-o:輸出的image名字 。
-F:使能“white-space-fixup”,如果是通過u-boot燒寫需要使能此功能。
-m:Nand Flash的最小讀寫單元,一般為page size。
-e:LEB size,說的是邏輯擦除塊大小,大家知道nand flash頁讀頁寫塊擦,一個設(shè)備多個塊,一個塊多個頁,一般也都是一個塊是64個頁,這樣算一下無論擦除塊大小就是2048*64=131072,-e的算法是物理擦除塊大小-2*頁大小,這里就是131072-2*2048=126976
-c說的是最大邏輯塊數(shù)量,這個很重要,不能大也不能小,太小也要大于image大小,太大mount有問題。計(jì)算起點(diǎn)是分區(qū)的物理塊數(shù)量,比如128MiB的mtd分區(qū),物理塊數(shù)量是128MiB/2048/64 = 1024個,需要減去2個壞塊保留塊,減去1個wear-leveling塊,還要減去1個eba的塊,等等,比如最終的值是1022,注意,如果物理上這個分區(qū)有壞塊的話,kernel會掃描到的,這時(shí)候,我們計(jì)算的這個值就要減去壞塊數(shù)了,否則會有邏輯塊大于物理塊數(shù)的內(nèi)核問題mount失敗,確切知道壞塊數(shù)是比較困難的,一般做法是做一個壞塊容忍數(shù),比如20個,這樣我們再減去20個壞塊,不要擔(dān)心這個會浪費(fèi)空間,ubinize的autoresize選項(xiàng)就是解決這個問題的。具體的這個值需要計(jì)算。!!!!
-x說的是壓縮方法,默認(rèn)是lzo,還支持zlib,zlib壓縮率高些,但是lzo壓縮解壓速度快 。
(2) ubinize
根據(jù)UBIFS image制作ubi.img,這個ubi.img是通過u-boot直接燒寫到nand flash分區(qū)上的。
ubinize -o system.ubi -m 2048 -p 131072 ubinize.cfg
-o說的是輸出image
-m還是頁大小
-p是物理擦除塊大小
ubinize.cfg是volume配置文件,例子如下:
[ubifs]
mode=ubi
image=system.ubifs #說的是mkfs.ubifs的結(jié)果
vol_id=0
vol_size=100MiB #說的是volume大小,用-e和-c的值做乘法計(jì)算,一般不用寫,autoresize會自動根據(jù)mtd分區(qū)大小適應(yīng),默認(rèn)值是image大小,寫了這個作用是幫助檢查image是否超過了分區(qū)限制,制作時(shí)候就提示,否則mount會出錯。-c的值是經(jīng)過計(jì)算的最大值了,不過autoresize參數(shù)會自適應(yīng)大小,不會浪費(fèi)空間的。
vol_type=dynamic
vol_alignment=1
vol_name=system #說的是分區(qū)名字
vol_flags=autoresize 5. ubifs燒寫
(1)mkfs.ubifs工具制作的結(jié)果,就是ubifs鏡像,不包含volume信息,需要用
nand erase.part system – 擦除分區(qū)
ubi part system - 激活分區(qū)
ubi create system - 創(chuàng)建分區(qū)
ubi write 84000000 system xxxxx - xxxxx表示鏡像實(shí)際大小
(2)ubi volume bin燒寫
mkfs.ubifs后,使用ubinize處理了ubifs的鏡像后,鏡像含有了volume信息,直接
nand write 84000000 system xxxxx - xxxxx表示鏡像實(shí)際大小
(3)示例
TI AM335x一份uboot下燒寫記錄:
可通過 u-boot 命令將生成的 ubi.img( 25M)燒寫到 NAND FLASH 分區(qū)上, 如下示例是將 ubi.img 先存儲到 SD 卡上,然后通過 u-boot 的 fatload 命令將其拷貝至內(nèi)存中。
u-boot# mw.b 0x82000000 0xFF
u-boot# mmc rescan
u-boot# fatload mmc 0 0x82000000 ubi.img
u-boot# nand erase 0x00780000 0xF880000
u-boot# nand write 0x82000000 0x00780000 0x1E00000
6. linux啟動參數(shù)設(shè)置
在 U-boot 下設(shè)置啟動信息如下:
#setenv bootargs 'console=ttyO0,115200n8 noinitrd ip=off mem=256M
rootwait=1 rw ubi.mtd=7,2048 rootfstype=ubifs root=ubi0:rootfs
init=/init'
可在命令行參數(shù)中增加多個ubi設(shè)備,如ubi.mtd=2,ubi.mtd=1,這樣傳遞后,內(nèi)核啟動后會做attach的操作,attach之后,/dev/下就建立好設(shè)備了。
7. ubifs mount
UBI character devices:
a) /dev/ubi0, /dev/ubi1, … – UBI devices: volume create, delete, re-size, and get device description operations
b) /dev/ubi0_0, /dev/ubi0_1, … - UBI volumes: read, write, update, and get volume description operations
Linux 系統(tǒng)中有關(guān)mtd和ubi的接口:
(1) cat /proc/mtd:可以看到當(dāng)前系統(tǒng)的各個mtd情況;
(2) cat /proc/partitions: 分區(qū)信息,有上面的類似;
(3) cat /sys/class/ubi/ubi0/*:當(dāng)前系統(tǒng)的ubi0情況
(4) ls /dev/*, 查看設(shè)備節(jié)點(diǎn)
假設(shè)我們想在mtdblock1上加載ubifs文件系統(tǒng),步驟如下:
(1)./ubiformat /dev/mtd1 -----格式化mtdblock1
(2)./ubiattach /dev/ubi_ctrl -m 1 -----將mtdblock1與ubi建立連接,命令輸出如下:
[ 977.342492] UBI: attaching mtd1 to ubi2
[ 977.346417] UBI: physical eraseblock size: 131072 bytes (128 KiB)
[ 977.352631] UBI: logical eraseblock size: 126976 bytes
[ 977.357948] UBI: smallest flash I/O unit: 2048 UBI device number 2, total 2000 LEBs (253952000 bytes, 242.2 MiB), available 1976 LEBs (250904576 bytes, 239.3 MiB), LEB size 126976 bytes (124.0 KiB)
系統(tǒng)自動將mtd1關(guān)連到ubi2上,假設(shè)系統(tǒng)中已經(jīng)存在ubi0, ubi1了。
(3) ls /sys/class/ubi/ -----可以看到該目錄下增加了一個ubi2的子目錄
(4) cat /sys/class/ubi/ubi2/dev -----可以得到該ubi2設(shè)備的主次設(shè)備號,如249:0
(5) cat /sys/class/ubi/ubi2/volumes_count -----結(jié)果為0,表示該ubi上沒有任何volume
(6) ls /dev/ubi* -----如果/dev中沒有ubi2, 則手工創(chuàng)建“mknod /dev/ubi2 c 249 0”
(7) ./ubimkvol /dev/ubi2 -s 100MiB -N my_ubi_vol -----在ubi2上創(chuàng)建一個volume
(8) ls /sys/class/ubi/ -----可以看到該目錄下增加一個ubi2_0的目錄,代表ubi2上的第一個volume,如果“cat /sys/class/ubi/ubi2_0/name”, 你可以得到“my_ubi_vol”,這就是(7)中的名字。
(9) cat /sys/class/ubi/ubi2_0/dev -----得到該volume的主次設(shè)備號,如249:1
(10) mknod /dev/ubi2_0 c 249 1 -----如果/dev中沒有ubi2_0, 則需要手工創(chuàng)建
(11) mount -t ubifs ubi2_0 /mnt -----將ubi2_0掛載到本地目錄 /mnt上,
(12) mount -----可以看到ubi2_0成功掛載在/mnt上。
linux源碼中Documentation/filesystems/ubifs.txt中含有ubifs mount的用法:
Mount options
=============
(*) == default.
bulk_read read more in one go to take advantage of flash media that read faster sequentially
no_bulk_read (*) do not bulk-read
no_chk_data_crc skip checking of CRCs on data nodes in order to
improve read performance. Use this option only
if the flash media is highly reliable. The effect
of this option is that corruption of the contents
of a file can go unnoticed.
chk_data_crc (*) do not skip checking CRCs on data nodes
compr=none override default compressor and set it to "none"
compr=lzo override default compressor and set it to "lzo"
compr=zlib override default compressor and set it to "zlib"
Quick usage instructions
========================
The UBI volume to mount is specified using "ubiX_Y" or "ubiX:NAME" syntax, where "X" is UBI device number, "Y" is UBI volume number, and "NAME" is UBI volume name.
Mount volume 0 on UBI device 0 to /mnt/ubifs:
$ mount -t ubifs ubi0_0 /mnt/ubifs
Mount "rootfs" volume of UBI device 0 to /mnt/ubifs ("rootfs" is volume name):
$ mount -t ubifs ubi0:rootfs /mnt/ubifs
The following is an example of the kernel boot arguments to attach mtd0 to UBI and mount volume "rootfs":
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
附:常見問題
(1) ubifs_check_node: bad CRC: calculated 0xca82b3d7, read 0x9be0e26
ubifs_check_node: bad node at LEB 51:45312
注意這個crc錯誤,說的錯誤并不是LED 0的問題,也就是說第一個邏輯塊沒問題,CRC是正確的,這個問題的一個解決辦法是要精確mkfs.ubifs時(shí)候的-c參數(shù)的值,不能太大了
(2)
[ 5.433349] UBIFS error (pid 71): ubifs_read_node: bad node type (150 but expected 1)
[ 5.434204] UBIFS error (pid 71): ubifs_read_node: bad node at LEB 524:4072, LEB mapping status 1
[ 5.435241] Not a node, first 24 bytes:
[ 5.435729] 00000000: 34 fb 21 ee 84 18 69 2d 60 b0 33 e6 74 f8 1c 15 da ca a1 c9 96 e3 ac 51 4.!...i-`.3.t..........Q
這個問題是,ubifs給nand驅(qū)動的buffer不一定是按照硬件對齊要求的,所以要驅(qū)動來判斷,dma等地址需要頁對齊等特性
(3) crc錯誤,但是LED 0:0
可能鏡像沒燒對,或者mtd-utils的版本和內(nèi)核版本相差較遠(yuǎn)
(4) 可以擦掉一個分區(qū),并不需要非要燒寫image到那個分區(qū),也可以直接mount的,這樣可以做實(shí)驗(yàn)驗(yàn)證ubi的性能,前提是kernel配置好了,mount正確了
(5) 如果是跟文件系統(tǒng)或者要手動mount,以下步驟供參考:
uboot下, mtd命令后,看到需要用ubifs的mtd分區(qū)的編號,比如
device nand0 <rda_nand>, # parts = 10
#: name size offset mask_flags
0: bootloader 0x00200000 0x00000000 0
1: boot 0x00800000 0x00800000 0
2: system 0x08000000 0x02000000 0
system分區(qū)mtd編號是2,命令如下:
nand erase.part system
命令行參數(shù)增加ubi.mtd=2,如果有多個,可以增加,如ubi.mtd=2,ubi.mtd=1,這樣傳遞后,內(nèi)核啟動后會做attach的操作,類似android的init中的attach那樣,attach之后,/dev/下就建立好設(shè)備了,進(jìn)入系統(tǒng)后用:內(nèi)核控制臺里,mount -t ubifs /dev/ubi0_0 /mnt 即可mount
參考:
http://www.cnblogs.com/linucos/p/3279381.html
Ubifs文件系統(tǒng)的制作和啟動—TI FAE
轉(zhuǎn)載于:https://www.cnblogs.com/embedded-linux/p/5674218.html
總結(jié)
- 上一篇: NLTK笔记
- 下一篇: J2EE基础之JSP