Zum Hauptinhalt springen

Flashfilesystem UBIFS

UBIFS vs. JFFS2

Using JFFS2 on NAND-Flash does have some disadvantages, like:

  • On mounting all descriptors of the filesystem get parsed. The bigger the filesystem is, the more time is needed to fulfill this task.
  • NAND-Flash can change its contents during a read-cycle. JFFS2 doesn't always handle this case correctly
  • By design a corrupt sector will be written into a new node, to save the data. But the old one doesn't get deleted or fixed. Instead the Filesystem will print an error during mount, until this sector gets overwritten again.

UBIFS fixes these and more disadvantages, resulting in a fast and reliable filesystem for NAND-Flash.

Using UBIFS

Configuration of the Kernel

using buildroot's "make linux26-menuconfig" the following parameters should be checked to be enabled

Device Drivers ==> MTD (Memory Technology Device) ==> UBI (Unsorted Block Images) ==> Support UBI

and

Filesystems ==> Misc Filesystems ==> UBIFS

Both points should be compiled into the kernel and thus be marked by an asterisk '*'. If they're compiled as modules only, booting from UBIFS won't be possible and the corresponding modules have to be loaded before they can be used.

Creating an UBIFS-filesystem

Before creating a filesystem, the correct partition should be chosen. While this can be any nand-partition, reading the file /proc/partitions and choosing the biggest one is a good decision most of the time. In the following example, the partition mtd2 will be used. More information about the mtd devices may be available from the command "mtdinfo /dev/mtdX"

Make sure to use the correct partition and not accidentally delete the kernel/bootloader ones.

Before creating a new partition, it is a good idea to make sure, that the partition is empty in advance. This can be done by executing

flash_eraseall /dev/mtd2

on newer kernel versions this command is no longer available. Instead use

flash_erase /dev/mtd2 0 0

If the file /dev/ubi_ctrl doesn't yet exist, it has to be created using mknod. The correct parameters should be read from /sys/class/misc/ubi_ctrl/dev

cat /sys/class/misc/ubi_ctrl/dev

10:63

mknod /dev/ubi_ctrl c 10 63

Afterwards the partition has to be made known to the UBI-layer of the Linux-kernel executing

ubiattach /dev/ubi_ctrl -m 2

Now, if the file /dev/ubi0 is not present on the system yet, read the file /proc/devices and create it accordingly

cat /proc/devices | grep ubi0

ubi0 253

mknod /dev/ubi0 c 253 0

To create a new ubifs you can use the following command now:

ubimkvol /dev/ubi0 -N root -s 200MiB

The filesystem will get formatted the first time it is used.

Mounting

To mount the created filesystem from a running system, use

mount -t ubifs ubi0:root /mnt

The correct partition must be attached first.

If the filesystem should be used as root-filesystem, the kernel must get known of the correct parameters in advance. So on the U-Boot commandline, set the correct bootargs. The number has to be replaced by the correct mtd-partition.

ICnova> setenv bootargs root=ubi0:root rootfstype=ubifs ubi.mtd=2

If the kernel should always boot with these parameters, execute saveenv afterwards.

Populating

The buildroot can't generate usable images directly, but using a TAR-Image, will generate reasonable results as well. To use this on the target, go into the directory, the partition was mounted to and extract it.

cd /mnt

tar -xpf /rootfs.arm.tar -C /mnt

sync

If the system booted via network does have the same contents, as the filesystem generated, it is enough to copy the contents of one filesystem to the other. Caution should be made not to copy any other mounted directories, too. The following lines should make the job:

cd /

cp -a bin boot dev etc home lib opt root sbin usr var mnt

cd mnt

mkdir tmp sys proc mnt

sync