2011年5月18日 星期三



linux 2.6.28 開始支援 ubifs.

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

Jffs2在mount時會scan整個flash所有的資料,再將檔案系統目錄儲存在system memory.
而當flash size越大所需的時間及system memory都將成線性倍數成長

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




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

UBIFS support write-back.


UBIFS supports on-the-flight compression.



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


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


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' 
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:

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

以下節錄 ti wiki


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

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

-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
-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
-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
-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
-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=]
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)