UBIFS vs. JFFS2
Using JFFS2 on NAND-Flash does have some disadvanteges, 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 it's 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 en error during mount, until this sector get's overwritten again.
UBIFS fixes these and more disadvantages, resulting in a fast and reliable filesystem for NAND-Flash.
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
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 wont 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 choosen. While this can be any nand-partition, reading the file /proc/partitions and choosing the biggest one is 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 parition, 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.
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.
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