2011年5月18日 星期三

UBIFS

有關ubifs的詳細介紹,請參考: 
http://www.linux-mtd.infradead.org/doc/ubi.html 
http://www.linux-mtd.infradead.org/doc/ubifs.html 


linux 2.6.28 開始支援 ubifs.

UBIFS 是由NOKIA Engineers開發用於Flash memory的檔案系統.
UBIFS可以視為下一代的Jffs2 file system.
與Jffs2一樣,UBIFS建構於MTD device之上而與一般的block device是不相容的.

1.Jffs2的架構與限制
Jffs2在mount時會scan整個flash所有的資料,再將檔案系統目錄儲存在system memory.
這種作法帶來的缺點是mount動作會消耗很多時間.
而當flash size越大所需的時間及system memory都將成線性倍數成長

Jffs2沒有write-back機制.(write-back : 先cache寫入的資料到一定的量再一次作write動作)
當Application寫入資料,Jffs2幾乎是同步將資料寫入實體flash.
會說幾乎是因為Jffs2的確有一塊NAND page size大小的buffer用來紀錄最後寫入的資料.
沒有write-back機制的缺點是對flash I/O的動作頻繁

Jffs2檔案存取所需要的時間跟檔案大小呈線性倍數成長

Jffs2如果歷經許多檔案小部份修改寫入動作,Jffs2的運作效率會逐漸變差.

2.UBIFS帶來的改進

UBIFS有個子系統UBI用以處理與MTD device之間的動作.
UBIFS檔案系統目錄儲存在flash上.這代表UBIFS mount時不需要scan整個flash的資料來重新建立檔案目錄.
因此mount所需時間約為幾百個ms而且不隨著flash size增加.

UBIFS support write-back.
寫入的資料會被cache住直到有必要寫入時才寫到flash.
這樣的作法降低分散小區塊數量及I/O效率.

但write-back非同步的寫入行為使得Application在寫入檔案時要謹慎處理同步問題.
重要的檔案使用fsync強迫UBIFS將資料寫入flash.

UBIFS supports on-the-flight compression.
UBIFS可壓縮檔案資料而且可選擇性壓縮部份檔案.

UBIFS具有日誌紀錄(journal)以減少檔案目錄更新的頻率

*使用方法

1. 先建立 ubifs image

a. 先將要製作的目錄作成 ubifs 格式

mkfs.ubifs -r -m  -e -c  -o -x 需要填入不同的參數
mkfs.ubifs -m 2048 -e 126976 -c 1872 -r ./mtd -o mtd.ubifs -x lzo
mkfs.ubifs -m 2048 -e 126976 -c 1872 -r ./mtd -o mtd.ubifs -x zlib
用 lzo or zlib 壓縮, default : lzo

PS: 

What is the the purpose of the -F (--space-fixup) mkfs.ubifs option?

Because of subtle ECC errors that can arise when programming NAND flash (see here), ubiformat is the recommended way of flashing a UBI image which contains a UBIFS file system. However, this is not always possible - for example, some embedded devices are manufactured using an industrial NAND flash programmer which has no knowledge of UBI or UBIFS.
The -F option causes mkfs.ubifs to set a special flag in the superblock, which triggers a "free space fixup" procedure in the kernel the very first time the filesystem is mounted. This fixup procedure involves finding all empty pages in the UBIFS file system and re-erasing them. This ensures that NAND pages which contain all 0xFF data get fully erased, which removes any problematic non-0xFF data from their OOB areas.
Of course it is not possible to re-erase individual NAND pages, and entire PEBs are erased. UBIFS performs this procedure by reading the useful (non 0xFF'ed) contents of LEBs and then invoking the atomic LEB change UBI operation. Obviously, this means that UBIFS has to read and write a lot of LEBs which takes time. But this happens only once, and the "free space fixup" procedure then unsets the "fixup" UBIFS superblock flag.
This option is supported if you are running a kernel version 3.0 or higher, or if you have pulled the changes from a UBIFS back-port tree. Note that ubiformat is still the preferred flashing method if the image is not being flashed for the first time, since it preserves existing erase counters (while using nandwrite or its equivalent does not).

b. 將上面的檔案做成可燒錄的 image

ubinize -o -m -p -s -O ubinize.cfg

ubinize 會吃 ubinize.cfg 來作成 image
ubinize -o ubifs.img -m 2048 -p 128KiB -s 512 -O 2048 ubinize.cfg

ubinize.cfg
[ubifs]
mode=ubi
image=mtd.ubifs
vol_id=0
vol_size=230MiB
vol_type=dynamic
vol_name=APPS
vol_flags=autoresize

PS: mkfs.ubifs -m 2048 -e 126976 -c 1888 → -e 為 logical eraseblock size(124KiB), 而不是 physical eraseblock size 的 128KiB, 有時好像是129024, 原因不明?
PS:  vol_size=230MiB 必須比實際的 mtd size 小.

2. 將 ubifs image 掛載起來


flash_eraseall /dev/mtdX
ubiformat /dev/mtd X -O 2048 -s 512 -f ubifs.img
ubiattach /dev/ubi_ctrl  -O 2048 -m X
mount -t ubifs ubi0_0 /mnt/mtd or mount -t ubifs ubi0:APPS /mnt/mtd

----------------------------------------------------------------------------------------------------------------------
指的是 mtd partition
ubi0:APPS  指的是 ubinize.cfg 裡的 vol_name
ubi0_0         指的是 ubinize.cfg 裡的 vol_id


如果要將 rootfs 用 ubifs 方式開機, boot command 為:

setenv bootargs 'console=ttyS0,115200 ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs' 
or
setenv bootargs 'console=ttyS0,115200 ubi.mtd=2 root=ubi0_0 rootfstype=ubifs' 
----------------------------------------------------------------------------------------------------------------------
root=ubi0:rootfs 指的是 ubinize.cfg 裡的 vol_name
root=ubi0_0       指的是 ubinize.cfg 裡的 vol_id

 當 ubiattach 時, 如果出現 error 9, 如下. 表示 flash mtd 的 size 太小

UBI error: vtbl_check: volume table check failed: record 7, error 9 Reference:
    http://www.plugcomputer.org/plugwiki/index.php/Enabling_UBIFS
    http://processors.wiki.ti.com/index.php/UBIFS_Support

不同版本的 mtd-utils 好像會有不同的參數 @@@@
以上都是用 mtd-utils 1.50 測試

----------------------------------------------------------------------------------------------------------------------
以下節錄 ti wiki

Calculations

Usable Size Calculation
As documented here, UBI reserves a certain amount of space for management and bad PEB handling operations. Specifically:
  • 2 PEBs are used to store the UBI volume table
  • 1 PEB is reserved for wear-leveling purposes;
  • 1 PEB is reserved for the atomic LEB change operation;
  • a % of PEBs is reserved for handling bad EBs. The default for NAND is 1%
  • UBI stores the erase counter (EC) and volume ID (VID) headers at the beginning of each PEB. 1 min I/O unit is required for each of these.
To calculate the full overhead, we need the following values:
SymbolMeaningValue for XO test case
SPPEB Size128KiB
SLLEB Size128KiB - 2 * 2KiB = 124 KiB
PTotal number of PEBs on the MTD device200MiB / 128KiB = 1600
BNumber of PEBs reserved for bad PEB handling1% of P = 16
OThe overhead related to storing EC and VID headers in bytes, i.e. O = SP - SL4KiB

UBI Overhead = (B + 4) * SP + O * (P - B - 4) 
      = (16 + 4) * 128Kib + 4 KiB * (1600 - 16 - 4)
      = 8880 KiB 
      = 69.375 PEBs (round to 69)
This leaves us with 1531 PEBs or 195968KiB available for user data.
Note that we used "-c 1580" in the above mkfs.ubifs command line to specify the maximum filesystem size, not "-c 1531" The reason for this is that mkfs.ubifs operates in terms of LEB size (124 KiB), not PEB size (128Kib). 195968KiB / 124 Kib = 1580.39 (round to 1580).
Volume size = 195968KiB (~192MiB)


----------------------------------------------------------------------------------------------------------------------

Usage: mkfs.ubifs [OPTIONS] target
Make a UBIFS file system image from an existing directory tree

Examples:
Build file system from directory /opt/img, writting the result in the ubifs.img file
mkfs.ubifs -m 512 -e 128KiB -c 100 -r /opt/img ubifs.img
The same, but writting directly to an UBI volume
mkfs.ubifs -r /opt/img /dev/ubi0_0
Creating an empty UBIFS filesystem on an UBI volume
mkfs.ubifs /dev/ubi0_0

Options:
-r, -d, --root=DIR       build file system from directory DIR
-m, --min-io-size=SIZE   minimum I/O unit size
-e, --leb-size=SIZE      logical erase block size
-c, --max-leb-cnt=COUNT  maximum logical erase block count
-o, --output=FILE        output to FILE
-j, --jrn-size=SIZE      journal size
-R, --reserved=SIZE      how much space should be reserved for the super-user
-x, --compr=TYPE         compression type - "lzo", "favor_lzo", "zlib" or
                         "none" (default: "lzo")
-X, --favor-percent      may only be used with favor LZO compression and defines
                         how many percent better zlib should compress to make
                         mkfs.ubifs use zlib instead of LZO (default 20%)
-f, --fanout=NUM         fanout NUM (default: 8)
-F, --space-fixup        file-system free space has to be fixed up on first mount
                         (requires kernel version 3.0 or greater)
-k, --keyhash=TYPE       key hash type - "r5" or "test" (default: "r5")
-p, --orph-lebs=COUNT    count of erase blocks for orphans (default: 1)
-D, --devtable=FILE      use device table FILE
-U, --squash-uids        squash owners making all files owned by root
-l, --log-lebs=COUNT     count of erase blocks for the log (used only for
                         debugging)
-v, --verbose            verbose operation
-V, --version            display version information
-g, --debug=LEVEL        display debug information (0 - none, 1 - statistics,
                         2 - files, 3 - more details)




Usage: ubinize [-o filename] [-p ] [-m ] [-s ] [-O ] [-e ]
[-x ] [-Q ] [-v] [-h] [-V] [--output=] [--peb-size=]
[--min-io-size=] [--sub-page-size=] [--vid-hdr-offset=]
[--erase-counter=] [--ubi-ver=] [--image-seq=] [--verbose] [--help]
[--version] ini-file
Example: ubinize -o ubi.img -p 16KiB -m 512 -s 256 cfg.ini - create UBI image
         'ubi.img' as described by configuration file 'cfg.ini'

-o, --output=     output file name
-p, --peb-size=       size of the physical eraseblock of the flash
                             this UBI image is created for in bytes,
                             kilobytes (KiB), or megabytes (MiB)
                             (mandatory parameter)
-m, --min-io-size=    minimum input/output unit size of the flash
                             in bytes
-s, --sub-page-size=  minimum input/output unit used for UBI
                             headers, e.g. sub-page size in case of NAND
                             flash (equivalent to the minimum input/output
                             unit size by default)
-O, --vid-hdr-offset=   offset if the VID header from start of the
                             physical eraseblock (default is the next
                             minimum I/O unit or sub-page after the EC
                             header)
-e, --erase-counter=    the erase counter value to put to EC headers
                             (default is 0)
-x, --ubi-ver=          UBI version number to put to EC headers
                             (default is 1)
-Q, --image-seq=        32-bit UBI image sequence number to use
                             (by default a random number is picked)
-v, --verbose                be verbose




Usage: ubiformat [-s ] [-O ] [-n]
[-f ] [-S ] [-e ] [-x ] [-y] [-q] [-v] [-h] [-v]
[--sub-page-size=] [--vid-hdr-offset=] [--no-volume-table]
[--flash-image=] [--image-size=] [--erase-counter=]
[--ubi-ver=] [--yes] [--quiet] [--verbose] [--help] [--version]

Example 1: ubiformat /dev/mtd0 -y - format MTD device number 0 and do
           not ask questions.
Example 2: ubiformat /dev/mtd0 -q -e 0 - format MTD device number 0,
           be quiet and force erase counter value 0.

-s, --sub-page-size=  minimum input/output unit used for UBI
                             headers, e.g. sub-page size in case of NAND
                             flash (equivalent to the minimum input/output
                             unit size by default)
-O, --vid-hdr-offset=  offset if the VID header from start of the
                             physical eraseblock (default is the next
                             minimum I/O unit or sub-page after the EC
                             header)
-n, --no-volume-table        only erase all eraseblock and preserve erase
                             counters, do not write empty volume table
-f, --flash-image=     flash image file, or '-' for stdin
-S, --image-size=     bytes in input, if not reading from file
-e, --erase-counter=  use as the erase counter value for all
                             eraseblocks
-x, --ubi-ver=          UBI version number to put to EC headers
                             (default is 1)
-Q, --image-seq=        32-bit UBI image sequence number to use
                             (by default a random number is picked)
-y, --yes                    assume the answer is "yes" for all question
                             this program would otherwise ask
-q, --quiet                  suppress progress percentage information
-v, --verbose                be verbose




Usage: ubiattach []
[-m ] [-d ] [-p ]
[--mtdn=] [--devn=]
[--dev-path=]
UBI control device defaults to /dev/ubi_ctrl if not supplied.
Example 1: ubiattach -p /dev/mtd0 - attach /dev/mtd0 to UBI
Example 2: ubiattach -m 0 - attach MTD device 0 (mtd0) to UBI
Example 3: ubiattach -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI
           and create UBI device number 3 (ubi3)

-d, --devn=   the number to assign to the newly created UBI device
                      (assigned automatically if this is not specified)
-p, --dev-path= path to MTD device node to attach
-m, --mtdn=   MTD device number to attach (alternative method, e.g
                      if the character device node does not exist)
-O, --vid-hdr-offset  VID header offset (do not specify this unless you really
                      know what you are doing, the default should be optimal)



沒有留言:

張貼留言