Episode #7 -- The Yoe Updater

In this episode we discus:

  • review of various Linux update technologies
  • discussion of experiments using swupdate
  • description of the Yoe updater
  • design ideas behind the Yoe updater
  • recent work done on the Yoe updater to make it more generic
  • Yoe handles installation, system initialization as well as update - this is very critical
  • designed to support products with long life cycles where things may change (partition layout, etc.)
  • how to add Yoe updater support to a new platform
  • what pieces of the system does the Yoe updater touch
  • how the Yoe updater handles rootfs corruption
  • why system initialization is important for reliable systems
  • why system initialization make sense in an initramfs
  • keep it simple is really the mantra
  • how the Yoe updater helps developers streamline their testing process by removing friction
  • future plans of managing updates using Simple IoT

See also the documentation and implementation.

1 Like

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

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.