using ubi on u-boot part one

October 26, 2010

[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]

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 (0x400000) 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

0x90AC0000 is some place on RAM different from ${loadaddr} (check using echo ${loadaddr}).