UBI stands for Unsorted Block Images. The shortest description for UBI is “LVM for NAND flash memory devices” and if you don’t know yet how it’s works I recommend check this presentation. I intend here describe my use with u-boot, starting with the steps to flash an kernel image. First of all, if you not defined MTDPARTS_DEFAULT on you u-boot config file, you must define (or redefine) on u-boot terminal.
> setenv mtdparts mtdparts=nand0:0x80000@0x0(uboot),0x400000@0x80000(kernel),-@0x480000(root)
If you type mtd you I’ll see:
device nand0 <nand0>, # parts = 3
#: name size offset mask_flags
0: uboot 0x00080000 0x00000000 0
1: kernel 0x00400000 0x00080000 0
2: root 0x1fb80000 0x00480000 0
UBI deal with volume and not partitions. Let’s create one.
> ubi part kernel
If you got some -22 error, like:
UBI error: ubi_read_volume_table: the layout volume was not found
UBI error: ubi_init: cannot attach mtd1
UBI error: ubi_init: UBI error: cannot initialize UBI, error -22
UBI init error -22
you need erase the NAND region [ nand erase 0x00080000 0x400000 ] and ubi part command again.
Next step is create the volume:
> ubi create kernel_vol
Creating dynamic volume kernel_vol of size 3354624
The value in bold is the max size of that volume in bytes (~3MB). Note that is less than the 4MB (0×400000) defined in mtdparts. This happens because UBI works with logical blocks instead (LEB) of physical ones (PEB).
In order to write the kernel you need transfer the image to u-boot. Since Ethernet isn’t working in my board I choose between serial or mmc. As serial is too slow to large files I opted to write the image on FAT partition on SD card and load through:
> mmcinfo
> fatload mmc 0 ${loadaddr} uImage
The output will be something like
reading uImage
2845120 bytes read
Finally write it:
> ubi write ${loadaddr} kernel_vol 0x2b69c0
You can check if everything went fine comparing
> ubi read 0x90AC0000 kernel_vol
> cmp.b ${loadaddr} 0x90ac0000 0x2b69c0
Total of 2845120 bytes were the same
0×90AC0000 is some place on RAM different from ${loadaddr} (check using echo ${loadaddr}).