I2SE (or now chargebyte) used to ship these devices with a simple Debian-based example firmware installed in the eMMC. These devices used the imx-bootlets project as bootloader. The eMMC consists only of the bootloader partition and one big root filesystem.
Later in time, I2SE used the RAUC project for there firmware updates. For this, they switched to a A/B system setup and changed the partitioning of the eMMC accordingly. The bootloader was also switched to U-Boot to support the switching between the A and B system. This concept was also kept when switching to Yocto-based BSPs.
Upgrading from an older Debian-based firmware to an Yocto-based firmware is not trivial when it should be done in the field. The reason is that you have to change the partitioning on-the-fly.
The following instructions demonstrates that such an update is technically possible and give you the files as example at hand.
Disclaimer: While the author of this document tested the whole procedure, there is no guarantee that it works flawlessly or applies to all real-world setups. There is a risk that you brick your devices and that it is not reachable again over network. Depending on what went wrong in this case, a technician might be required at the charger to physically replace the board.
The main problem is that you cannot re-partition the eMMC while it is in use by the Linux kernel. The solution is to use a tiny RAM-based Linux system which solely operates during the hot phase of the migration. The main idea used here is, that the “old” system is prepared, then runs the migration and finally boots into the fully updated system running Yocto.
During the preparation phase of the old system, at least three files have to be downloaded to the old root filesystem:
The install procedure provides two hooks for your customizations: one hook is available before the actual migration was started, e.g. to save some configuration data, one hook is available after the eMMC was updated.
The RAM-based Linux configures the network interface for DHCP. Also an SSH server is started – without any password set. That means that during the migration any user on the network could log into the system as user root.
It is out of scope of this document, how the files are transferred to the old system. You need at least:
You have to place these two files first in the correct location before installing the migration firmware. Otherwise, the migration firmware would already boot-up in case of sudden power-losses and finds nothing to use.
The migration firmware: mmcblk0p1.img
This file must be written to the old bootloader partition. In
contains the described RAM-based Linux system. Use e.g. the following
command: dd of=/dev/mmcblk0p1 if=mmcblk0p1.img
Optional files can be placed in the root filesystem:
For your information, here is the actual migration shell script used by the firmware:
#!/bin/sh # Assumptions: # The image of the new target rootfs is gz compressed and # stored in the root directory (/) of the old rootfs (/dev/mmcblk0p2) # with a filename ending in '*.rootfs.ext4.gz'. # The boot loader U-Boot is stored at the same location # with filename ending in '*.sb' # exit on errors set -e # fs check is required before resize e2fsck -y -f /dev/mmcblk0p2 # shrink current filesystem so that it fits smaller than final two rootfs resize2fs -f /dev/mmcblk0p2 2032M || true # re-partition first round - create future /srv partition already at its final location cat <<EOF | sfdisk /dev/mmcblk0 label: dos label-id: 0x5452574f device: /dev/mmcblk0 unit: sectors /dev/mmcblk0p1 : start= 2048, size= 16384, type=53, bootable /dev/mmcblk0p2 : start= 20480, size= 4161536, type=83 /dev/mmcblk0p3 : start= 4212736, size= 2097152, type=83 EOF # format /srv mkfs.ext4 -F -F /dev/mmcblk0p3 # mount old rootfs and /srv mount /dev/mmcblk0p2 /mnt mkdir -p /srv mount /dev/mmcblk0p3 /srv # save file we still need from old rootfs cp /mnt/*.sb /srv cp /mnt/*.rootfs.ext4.gz /srv # run pre-install hook if present [ -x /mnt/install-pre-hook.sh ] && . /mnt/install-pre-hook.sh # umount again - partition number will change umount /mnt /srv # re-partition 2nd time - final partition layout cat <<EOF | sfdisk /dev/mmcblk0 label: dos label-id: 0x6d686569 device: /dev/mmcblk0 unit: sectors /dev/mmcblk0p1 : start= 2048, size= 14336, type=53 /dev/mmcblk0p2 : start= 16384, size= 2097152, type=83 /dev/mmcblk0p3 : start= 2113536, size= 2097152, type=83 /dev/mmcblk0p4 : start= 4210688, size= 2627584, type=5 /dev/mmcblk0p5 : start= 4212736, size= 2097152, type=83 /dev/mmcblk0p6 : start= 6311936, size= 262144, type=83 /dev/mmcblk0p7 : start= 6576128, size= 262144, type=83 EOF # mount /srv again mount /dev/mmcblk0p5 /srv if [ -z "$SKIP_ROOTFS2" ]; then # write rootfs partition 2 zcat /srv/*.rootfs.ext4.gz | dd of=/dev/mmcblk0p3 bs=4M resize2fs /dev/mmcblk0p3 fi # write rootfs partition 1 zcat /srv/*.rootfs.ext4.gz | dd of=/dev/mmcblk0p2 bs=4M resize2fs /dev/mmcblk0p2 # cleanup U-Boot environment dd if=/dev/zero of=/dev/mmcblk0 bs=1k count=128 seek=128 dd if=/dev/zero of=/dev/mmcblk0 bs=1k count=128 seek=256 # write U-Boot sdimage -f /srv/*.sb -d /dev/mmcblk0 # cleanup & reboot umount /srv sync # run pre-install hook if present [ -x /mnt/install-post-hook.sh ] && . /mnt/install-post-hook.sh reboot
As you can see, if something goes wrong, the script terminates and the system is remains in this state – it is reachable via SSH until the next power cycle. After a power cycle, it depends whether the new bootloader was already installed or whether the migration firmware is still in place.
There is also a small weakness of the whole procedure: a power outage during the bootloader installation will most probably brick the system. This is why it is done last. In case a power outage happens before, then the whole re-flashing procedure is simply restarted from scratch.
As found out later, there exists an even older partitioning scheme consisting of 4 partitions: a FAT partition, the bootstream partition, the root filesystem and yet another ext4 partition.
Also these devices can be migrated to the new Yocto approach. Here the advantage is that the rootfs partition must not be reduced in size during the conversion. However, the bootstream partition is in the way and thus moved so that the system should survive a potential power outage during the migration process.
The migration script was adapted accordingly, the latest version can be found on Github, see below. But while the tiny migration Linux system is in core the same, the partition image is slightly different due to other offsets in the bootstream headers.
So you have to use the following migration firmware: mmcblk0p2.img
The installation and remaining features are the same, just replace the content of the second partition with the provided file.
Last update: 2025-01-10, mhei