Back to the Overview

Over-the-Air (OTA) Update / System Upgrade

ELinOS, Linux, Security

Available in ELinOS 7.0.2 or higher: www.sysgo.com/elinos

Devices and software components nowadays are getting more complex. Especially the software provides a huge set of functionality and thus is a potential security risk. Thus it is common to have an update strategy available to do a system upgrade. The easiest way is to provide software updates over-the-air (SOTA). For this purpose ELinOS provides the tool SWUpdate.

SWUpdate is a powerful tool to support the user to provide customized update strategy for its system. The tool supports multiple strategies and is highly configurable. Thus it can be used to update a single user application only or provide a full partition image with a pre and post install processes. SWUpdate uses a single CPIO image and can integrate multiple files or partition images. It is even possible to support different target boards and multiple software channels (stable, debug, …) in a single update image.

Integrate SWUpdate

The tool mainly consists of a set of binaries. In ELinOS the package swupdate contains all required tools and can be simply copied onto the target file system. Most other distributions provides a package as well.

Generate an Update Image

All images require a file called sw-description. The following template updates a single file or application called test_appl. This application will be stored in /usr/bin/ on the target system.

sw-description

software =
{
    version = "1.0";
 
    files: (
        {
            filename = "test_appl";
            path = "/usr/bin/test_appl";
        }
    );
}

This description provides an initial configuration.

In order to generate the image file please use the following script. It generates the CPIO image called update.swu by using the files sw-description and test_appl:

# ls -f sw-description test_appl | cpio -ov -H crc > update.swu

The update image contains all information required for SWUpdate.

Note that the filename is in the sw-description is used as an identifier, so the same exact path has to be used when creating the cpio archive.

Installing the Update Image

The easiest way to update the system is to call SWUpdate directly with the update image:

# swupdate -i update.swu
Swupdate v2020.11.0
 
Licensed under GPLv2. See source distribution for detailed copyright notices.
 
Software updated successfully
Please reboot the device to start the new software
[INFO ] : SWUPDATE successful !
#

‘--verbose‘ argument is needed to show more details about the update process.

Add Pre-/Post Installation Script

It might be useful to have more control before or after the installation. For this purpose you can add a bash script:

update.sh

#!/bin/bash
 
echo "Updating system..."
# post step
echo "Update finished"

sw-description

sw-description
software =
{
    ...
    scripts: (
        {
            filename = "update.sh";
            type = "postinstall";
        }
    );
}

In order to see the output of the script in the log, the --verbose argument is required.

By default, the system restart is not performed after update - the swupdate option -p, --postupdate may be use to specify e.g. the 'reboot' command to be used.

Add version check

SWUpdate supports version checking by comparing /etc/sw-versions with a version number provided in the sw-description for each component:

software =
{
    version = "1.0";
 
    files: (
        {
            name = "test_appl";
            version = "1.0";
            install-if-different = true;
 
            filename = "test_appl";
            path = "/usr/bin/test_appl";
            preserve-attributes = true;
        }
    ...
}

Please make sure each component contains the fields name, version and install-if-different. These fields are used to compare the provided version with the one already installed by looking into /etc/sw-versions. It is up to the integrator to provide the initial version of the sw-version. The content has the following syntax:

<name of component>    <version>

Using 'swupdate -i' automatically checks the version number and installs the component only in case the versions differ.

Full System Update

Instead of updating single files SWUpdate can update a partition as well. This is useful if you plan to update the whole system image. The system integrator is free to select an update strategy which fits into the concept and system requirements. For example you can use a single or dual copy root file system. We are using the single copy strategy with a rescue system.

For this scenario you need two partitions. The first one contains the rescue system with kernel and SWUpdate, the second one the real root file system. The following simple description file uses a single raw image called rootfs.img which is stored to /dev/XXX on the target. Please adapt the partition name to the correct partition.

sw-description

software =
{
    version = "1.0";
 
    images: (
        {
            filename = "rootfs.img";
            device = "/dev/XXX";
        }
    );
}

On the target console you are still calling 'swupdate -i' to start the update. The tool writes the content of rootfs.img directly into the partition.

Full System Update with ELinOS on QEMU

In ELinOS you can easily test the system update by using QEMU. The SWUpdate package includes a preconfigured web server.

Please create two new project with the following features:

Rescue System

  • SquashFS root file system
  • Enable network support
  • Add SWUpdate package to the root filesystem

Main System

  • SquashFS root file system
  • Additional user required features

SquashFS automatically enables VirtIO block support and provides the required QEMU options to use a root filesystem image stored on the development system. 

After building both projects the root file systems are stored in the file rootfs.squashfs in each project folder. For our purpose we need to create a new image providing two partitions. The first one contains the current root file system. The second one is used by SWUpdate as the update partition.

Please switch to the rescue project and execute the following commands to create a new disk image providing two partitions. The first partition contains the rescue system and the second one the main system.

# dd if=/dev/zero bs=1M count=100 of=rootfs.img
# fdisk rootfs.img
-> create two partitions
# dd if=rootfs.squashfs of=rootfs.img conv=notrunc bs=512 seek=2048
-> stores the current ELinOS root filesystem in the first partition

Next step creates the update image containing the main system.

software =
{
    version = "1.0";
 
    images: (
        {
            filename = "PATH/rootfs.squashfs";
            device = "/dev/vda2";
        }
    );
}
ls -f sw-description PATH/rootfs.squashfs | cpio -ov -H crc > update.swu

Now you can start QEMU by using rootfs.img as the drive filename and /dev/vda1 as root partition.

When QEMU has been started two partitions are available vda1 and vda2. vda1 is used by the current rescue system and vda2 is empty.

Start SWUpdate in daemon mode with WebServer:

# swupdate -w '-p 8080 -r /var/www'

Now you can connect to the web interface of SWUpdate running on port 8080: http://x.x.x.x:8080/



You can drag and drop the previously created update.swu into this window to start the update process:



After some time the update image has been transferred and installed into the main partition (vda2). After that you can switch to the main system. This is normally done by the bootloader but in our case we have to restart QEMU and  use /dev/vda2 as root partition.