UBIFS root filesystem flash update on ccardimx28js

Hi all,

I am using Yocto to create images for a ConnectCard Jump Start reference board (ccardimx28js). An issue arises when I attempt to update a secondary rootfs partition within Linux from the primary partition using the update_flash tool. Both rootfs-es are in a UBIFS format.

The digi-embedded-yocto (dey) minimal, non-graphical build is a starting point for my images, which include some minor customizations to include additional python packages and an application-specific program baked into the firmware.

I have two identical UBIFS rootfs filesystems, 50MB in size. I can flash these via tftp from uboot using the Digi update feature. And can boot into either the primary or secondary Linux system and run my application as expected.

As part of a firmware update feature, a requirement exists to update the rootfs if and when a new application is available or an update to the filesystem is desired.

This update is to be invoked from the application running on Linux and will update the other (currently unmounted) rootfs. Coupled with some additional logic, this ping-pong mechanism will be used to ensure a robust system in the event that a firmware update fails due to bad image contents, some file transmittal corruption, power loss during update, etc.

The update procedure is demonstrably correct when doing the UBIFS rootfs updates from u-boot. This uses the Digi update command as referenced above.

The update fails during image prechecks when invoking the procedure within Linux. This uses the Linux tool update_flash. Specifically, the image validation prechecks complain that the image size is not a multiple of the physical erase block (PEB) size, 131072 bytes, viz.

root@ccardimx28js:/dev# update_flash dey-image-minimal-ccardimx28js-20151003000022.128.rootfs.ubifs 6
Partition 6 is NAND ()
Full Size: 51200 KiB
Good Size: 51200 KiB
Verifying File(s): dey-image-minimal-ccardimx28js-20151003000022.128.rootfs.ubifs
dey-image-minimal-ccardimx28js-20151003000022.128.rootfs.ubifs (33480 KiB)
Flashing: FAILED! (ubiformat: error!: file “dey-image-minimal-ccardimx28js-20151003000022.128.rootfs.ubifs” (size 34283520 bytes) is not
multiple of eraseblock size (131072 bytes))

The error flagged by the prechecks seems legitimate, i.e. the UBIFS image size is not a multiple of the PEB. However, I do not see how to get the DEY yocto or the recipes used by it to generate a compatible sized image, nor do I understand how the update utility running from u-boot deals with this using the identical image.

Additionally, the parameters in the DEY configuration for the ccardimx28js seem to have correct sizes for the PEB and LEB. There is one other place in meta-fsl-arm that has MKUBIFS_NAND_ARGS that seem to be incompatible, but changing those had no effect on the built image size.

Thanks in advance for insight into the problem.

update_flash does not support ubifs images, ubi images are not generated so if you want to update a partition with ubifs image, it is possible but needs some manual work.
Currently digi does not generate ubi volumes in DEY.

Please take a look at what is described here as solution A. Otherwise Solution B from below should work as well:

Solution A – On a booted Linux system

I think it’s the best method to understand how UBI is structured.

You first need to enable UBI and UBIFS in the kernel and install the mtd-utils package (for Debian and Ubuntu) on your box. You may also compile mtd-utils from its sources.

Once you have your UBIFS image at hand, let’s sing the UBI song:

ubiformat /dev/mtdX

ubiattach -p /dev/mtdX

ubimkvol /dev/ubi0 -N volume_name -s 64MiB

ubiupdatevol /dev/ubi0_0 /path/to/ubifs.img

mount -t ubifs ubi0:volume_name /mount/point

Let’s examine each command. ubiformat erases an MTD partition but keeps its erase counters ((‘X’ is the number of the partition you want to use). ubiattach creates a UBI device from the MTD partition. This UBI device is then referred to by UBI as ubi0 (if it is the first device). ubimkvol creates a volume on a UBI device ; this volume is referred to as ubi0_0 (if it is the first volume on the device). ubiupdatevol puts an image on an empty volume. (use ubiupdatevol -t /dev/ubi0_0 to empty a volume). At last, the well-known mount can be invoked using :

Solution B – Prepare a UBI image ready to be flashed

It is more common to directly flash filesystem images directly from the bootloader. It is made possible by ubinize to prepare a UBI device image containing one or more volumes.

ubinize reads a configuration file (in the very simple INI format) describing the volumes and their configuration. Here is an example of a device with two volumes ; one, named rootfs is read-only (static), the other one, data is read-write (dynamic) ; the autoresize flag makes UBI resize to volume to use the whole unused space at initialization. The name of the sections is totally arbitrary.


Next is the generation of the UBI image. The ubinize utility will need the Physical Erase Block size (PEB) (option -p) and the minimum I/O size (-m):

ubinize -vv -o -m

-p KiB
Your image is ready. You may now want to boot on the rootfs UBIFS partition.

Here is another example that should help you:
Writing a UBIFS image to flash

Digi Embedded Linux/Yocto generates UBIFS images for the flash of embedded devices. U-Boot can write such images to a UBIFS partition using the update command. The following article explains how to do the same in Linux.
NFS file system: If you want to write a UBIFS image from Linux it is likely that you want to write the root file system so you should be booting a system from NFS.
If you are writing a secondary rootfs or non-rootfs partition, you do not have to use NFS
mtdutils: in order to manage the UBI device you need to have the mtdutils package in your target device.
Erased partition: some of the mtdutils may fail over an unclean partition. It is recommended that the partition is erased from U-Boot with erase_pt .
Create a UBIFS file out of a folder contents
In your host computer, you can create a UBIFS image out of the contents of a folder using the mkfs.ubifs command and providing some geometry parameters of the target flash:
Page size (the physical size of the flash page)
LEB size (the logical erase block size, normally the physical erase block size minus the UBI data offset)
Max LEB count (this can be a number bigger than the number of good physical erase blocks -PEB-)
user@host:~$ mkfs.ubifs -m 4096 -e 248KiB -c 511 -r source_folder/ /tmp/myimage.ubifs
Attach UBI device
The command ubiattach tells the system that it must create a UBI device on a certain MTD partition. For example to create a UBI device on partition /dev/mtd4:
root@ccardimx28js:~# ubiattach -m 4
This creates a new device /dev/ubi0.

In case you need to specify the ubi control device, the syntax is ubiattach -m 4 /dev/ubi_ctrl

Create UBI volume
One or more volumes can be created within a UBI device. Normally we only create one per device using the maximum volume size:
root@ccardimx28js:~# ubimkvol /dev/ubi0 -m -N RootFS
This creates a device node /dev/ubi0_0.
Write the UBIFS image to the volume
Finally, write the UBIFS image to the volume:
root@ccardimx28js:~# ubiupdatevol /dev/ubi0_0 /tmp/myimage.ubifs
Detaching the UBI device
After your are done with your device, you can safely detach it with:

ubidetach -d 4