Recently had to modify the flash partition setup in deployed product as we need more rootfs space. The original partition layout was for 128MB NAND flash, but the product has always shipped with 512MB, and we’re out of rootfs space, so time to forget about 128MB (potential cost savings) and go forward.
Using our handy calculator, we have the old and new layouts:
Old Partitions
Device Name Start Size(B) Size(MiB) Size(Blks)
mtd0 spl 0x0 0x200000 2 16
mtd1 uboot 0x200000 0x200000 2 16
mtd2 uboot env 0x400000 0x200000 2 16
mtd3 linux 0x600000 0xc00000 12 96
mtd4 rootfs 0x1200000 0x2d00000 45 360
mtd5 data 0x3f00000 0x4100000 65 520
total size = 0x8000000, 128MiB
New Partitions
Device Name Start Size(B) Size(MiB) Size(Blks)
mtd0 spl 0x0 0x200000 2 16
mtd1 uboot 0x200000 0x200000 2 16
mtd2 uboot env 0x400000 0x200000 2 16
mtd3 linux 0x600000 0x2800000 40 320
mtd4 rootfs 0x2e00000 0xc800000 200 1600
mtd5 data 0xf600000 0x10a00000 266 2128
total size = 0x20000000, 512MiB
To make the change, I modified:
- the MTD layout in the kernel device tree file
- configure u-boot to load more kernel bits when booting
And that’s it – generate a new image, drop it on a UBS disk, insert into unit, and on next boot it installs the updated system in the new partition layout.
Why does this work? We package the updater in the kernel initramfs. If we detect the kernel has changed, we reprogram the kernel and reboot. Then the new kernel/updater is now running. If the flash partitions are not working properly, we re-format the flash in the updater, and then proceed to install. Having the following packaged together makes for a very robust system:
- kernel
- initramfs
- updater
- storage formatting
- any system initialization
- update functionality
- updater
It this system, we did not need to migrate the data in the data partition as a new configuration file will automatically get sync’d down to the device if it is missing or not current, and there is no other data we need to preserve.