What is Unsorted Block Image (UBI)?

The Unsorted Block Image File System (UBIFS) is designed to operate on raw flash devices. It was first introduced into the 2.6.27 Linux Kernel in October 2008.

UBIFS works on an Unsorted Block Image (UBI) device which provides tracking of bad flash blocks and wear leveling. UBI works on top of MTD.

For further information see :

Obtaining details of the Flash Device

Before we can start building UBIFS and UBI images, we need to know details of the flash device fitted on the GuruPlug. This can be achieved by running mtdinfo -a on our target device, i.e. the GuruPlug.

Pay particular attention to the Eraseblock size, Sub-page size, Minimum input/output unit size and the number of eraseblocks for the partition where our UBIFS will reside.

# mtdinfo -a
Count of MTD devices:           3
Present MTD devices:            mtd0, mtd1, mtd2
Sysfs interface supported:      yes

mtd0
Name:                           u-boot
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          8 (1048576 bytes, 1024.0 KiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:0
Bad blocks are allowed:         true
Device is writable:             true

mtd1
Name:                           uImage
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          32 (4194304 bytes, 4.0 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:2
Bad blocks are allowed:         true
Device is writable:             true

mtd2
Name:                           root
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          4056 (531628032 bytes, 507.0 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  512 bytes
OOB size:                       64 bytes
Character device major/minor:   90:4
Bad blocks are allowed:         true
Device is writable:             true

Building an UBIFS

Make a ZLIB compressed (-x zlib) UBI filesystem image with a minimum I/O unit size of 2048 bytes (-m 2048), a logical erase block (LEB) size of 129024 bytes and a maximum logical erase block count of 4056:

# mkfs.ubifs -v -x zlib -m 2048 -e 129024 -c 4056 -r rootfs-f12/ rootfs.ubifs.img
mkfs.ubifs
	root:         rootfs-f12/
	min_io_size:  2048
	leb_size:     129024
	max_leb_cnt:  4056
	output:       rootfs.ubifs.img
	jrn_size:     8388608
	reserved:     0
	compr:        zlib
	keyhash:      r5
	fanout:       8
	orph_lebs:    1
	space_fixup:  0
	super lebs:   1
	master lebs:  2
	log_lebs:     5
	lpt_lebs:     2
	orph_lebs:    1
	main_lebs:    1132
	gc lebs:      1
	index lebs:   26
	leb_cnt:      1143
	UUID:         0CE735AE-7BD5-4CE8-A326-8CF8308A133F
Success!

Building an UBI Image

Next, we build an UBI image containing the above filesystem as one volume. Create a configuration file called ubi.cfg containing the following :

[ubifs]
mode=ubi
image=rootfs.ubifs.img
vol_id=0
vol_size=400MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
# ubinize -v -o rootfs.ubi.img -m 2048 -p 128KiB -s 512 -O 512 ubi.cfg
ubinize: LEB size:                  129024
ubinize: PEB size:                  131072
ubinize: min. I/O size:             2048
ubinize: sub-page size:             512
ubinize: VID offset:                512
ubinize: data offset:               2048
ubinize: UBI image sequence number: 2057591195
ubinize: loaded the ini-file "ubi.cfg"
ubinize: count of sections: 1

ubinize: parsing section "ubifs"
ubinize: mode=ubi, keep parsing
ubinize: volume type: dynamic
ubinize: volume ID: 0
ubinize: volume size: 419430400 bytes
ubinize: volume name: rootfs
ubinize: volume alignment: 1
ubinize: autoresize flags found
ubinize: adding volume 0
ubinize: writing volume 0
ubinize: image file: rootfs.ubifs.img

ubinize: writing layout volume
ubinize: done

Flashing

It is advisable not to use nandwrite to flash an UBI image. For more information, see here.

The recommended method is to use ubiformat as this not only preserves the erase counters used for wear leveling, it prevents ECC errors on some NAND flash devices.

ubiformat is not available from the bootloader, thus you need to undertake this task on a bootable GuruPlug. I normally boot using root NFS to carry out this operation.

From the shell on the GuruPlug:

# flash_erase /dev/mtd2 0 0 
# ubiformat /dev/mtd2 -s 512 -O 512 -f rootfs.ubi.img

Testing

You can test an newly flashed image prior to loading it as the root filesystem (i.e. while using root NFS).

First attach the desired MTD partition to UBI using the ubiattach command. Once this is successful, you can mount the UBIFS.

ubiattach -p /dev/mtd2
mount -t ubifs /dev/ubi0_0 /mnt/ubifs/


Boot Messages

Below is the kernel messages of a system booting from the above UBIFS :

NAND device: Manufacturer ID: 0xec, Chip ID: 0xdc (Samsung NAND 512MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 3 MTD partitions on "orion_nand":
0x000000000000-0x000000100000 : "u-boot"
0x000000100000-0x000000500000 : "uImage"
0x000000500000-0x000020000000 : "root"
UBI: attaching mtd2 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: max. sequence number:       0
UBI: volume 0 ("rootfs") re-sized from 3251 to 4012 LEBs
UBI: attached mtd2 to ubi0
UBI: MTD device name:            "root"
UBI: MTD device size:            507 MiB
UBI: number of good PEBs:        4056
UBI: number of bad PEBs:         0
UBI: number of corrupted PEBs:   0
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: 4056
UBI: number of PEBs reserved for bad PEB handling: 40
UBI: max/mean erase counter: 0/0
UBI: image sequence number:  576084514
UBI: background thread "ubi_bgt0d" started, PID 461

...

UBIFS: mounted UBI device 0, volume 0, name "rootfs"
UBIFS: file system size:   516225024 bytes (504126 KiB, 492 MiB, 4001 LEBs)
UBIFS: journal size:       9033728 bytes (8822 KiB, 8 MiB, 71 LEBs)
UBIFS: media format:       w4/r0 (latest is w4/r0)
UBIFS: default compressor: zlib
UBIFS: reserved for root:  0 bytes (0 KiB)
VFS: Mounted root (ubifs filesystem) on device 0:13.