SWUpdate¶
SWUpdate Introduction¶
SWUpdate is a Linux Update agent with the goal to provide an efficient and safe way to update an embedded system. SWUpdate supports local and remote updates, multiple update strategies and it can be well integrated in the Yocto build system by adding the meta-swupdate layer.
It supports the common media on embedded devices such as as NAND flashes, UBI volumes, SD / eMMC, and can be easily extended to introduce project specific update procedures. Pre- and postinstall scripts are supported, and a LUA interpreter helps to customize the update process. An update package is described by the sw-description file, using the libconfig syntax or JSON. It is even possible to use Lua with a custom syntax.
Here is a short list of the main features:
- Install on embedded media (eMMC, SD, NAND flash)
- Allow delivery single image for multiple devices
- Multiple interfaces for getting software
- local storage
- integrated web server
- integrated REST client connector to hawkBit
- remote server download
- Software delivered as images, gzipped tarball, etc.
- Allow custom handlers for installing FPGA firmware, microcontroller firmware via custom protocols.
- Power-Off safe
- Hardware / Software compatibility.
SWUpdate is developed by Stefano Babic from DENX, and is licensed under GPL Version 2.0+ You can check SWUpdate's online documentation at: http://sbabic.github.io/swupdate This Introduction was taken from the SWUpdate README.md at: https://github.com/sbabic/swupdate
Example of using the meta-swupdate layer with Variscite i.MX boards is provided in the meta-variscite-sdk-imx layer. This example uses the double-copy approach, using two rootfs partitions on eMMC.
Double copy with fall-back¶
If there is enough space on the storage to save two copies of the whole software, it is possible to guarantee that there is always a working copy even if the software update is interrupted or a power off occurs.
Each copy must contain the kernel, the root file system, and each further component that can be updated. It is required a mechanism to identify which version is running.
SWUpdate should be inserted in the application software, and the application software will trigger it when an update is required. The duty of SWUpdate is to update the stand-by copy, leaving the running copy of the software untouched.
A synergy with the boot loader is often necessary, because the boot loader must decide which copy should be started. Again, it must be possible to switch between the two copies. After a reboot, the boot loader decides which copy should run.
Summary:
- Requires twice as much space than single copy
- Guarantees there’s always a working copy!
- Bootloader is in charge of booting proper image
Single copy – running as standalone image¶
The software upgrade application consists of kernel (maybe reduced dropping not required drivers) and a small root file system, with the application and its libraries. The whole size is much less than a single copy of the system software (2.5MB-8 MB).The system can be put in “upgrade” mode, simply signaling to the boot loader that the upgrading software must be started (either by using boot loader environment or GPIO).
The boot loader starts “SWUpdate”, booting the SWUpdate kernel and the initrd image as root file system. Because it runs in RAM, it is possible to upgrade the whole storage. Differently as in the double-copy strategy, the systems must reboot to put itself in update mode.
This concept consumes less space in storage as having two copies, but it does not guarantee a fall-back without updating again the software. However, it can be guaranteed that the system goes automatically in upgrade mode when the productivity software is not found or corrupted, as well as when the upgrade process is interrupted for some reason.
Summary:
- Stand alone image consists of kernel / dt + initrd
- Much smaller than entire system
- Bootloader in charge of loading standalone image
- System must reboot to enter update process
Update image format¶
The main concept is that the manufacturer delivers a single .swu image.
The .swu image may contain multiple images and files. In addition, it must contain a sw-description file with meta information about the image.

See the following link for info about the sw-description file syntax: https://sbabic.github.io/swupdate/sw-description.html
Update methods¶
Important: By default, SWUpdate saves temporary files to the /tmp directory, which resides in system RAM. On systems with limited RAM, this may lead to issues. To avoid such problems, you can specify an alternate directory by setting the TMPDIR environment variable.
Update via console¶
To start SWUpdate expecting the image from a file:
To extract temporary files to the home directory instead of /tmp:
The -H option and its parameter is optional. The command can be simplified to
as long as a file named
is present in the rootfs and it's populated with the following content
Please note that no multiple instances of swupdate can be running simultaneously: if the rootfs contains the service to start the swupdate web-server, the server must be stopped before running swupdate from command line
You can schedule an auto update from a removable storage by editing the automount sequence, making it trigger the update command above, each time a removable device is inserted.
Update via http¶
OTA update is available via http protocol: It is possible to configure the software update agent to include embedded web-server (CONFIG_MONGOOSE). To start SWUpdate with the embedded web-server:
The TMPDIR and hwrevision explained above can still be used:
The default port of the Web-server is 8080. You can then connect to the target with:
And upload the .swu file.
The start page:
And after a successful update:

To see all of the command line parameters of swupdate:
Yocto Integration¶
Variscite provides an example for the double-copy approach, where the rootfs is on eMMC.
Recipes¶
Before you begin, get familiar with the Variscite Yocto Build Release guide.
Variscite provides the following two image recipes:
- var-image-swupdate - Based on fsl-image-gui (the default Variscite demo image with a GUI without any Qt content) with the following differences:
- swupdate and swupdate-www packages are included
- The kernel image and device trees are added to the /boot directory of the rootfs (by including the kernel-image and kernel-devicetree packages), instead of using a BOOT partition
- The rootfs is created only as a tar.gz archive (IMAGE_FSTYPES = "tar.gz")
See the recommended internal storage layout for double-copy approach:

- var-image-swu - This recipe creates an .swu update image using the var-image-swupdate image
The following is the sw-description file used by the Variscite sample update image recipe (var-image-swu). This sample image consists of two components: - A root file system (including the kernel), which is created by the var-image-swupdate recipe - A bash script that runs before (called with preinst argument) and after (called with postinst argument) the installation of the root file system.
software =
{
version = "0.1.0";
imx8mp-var-dart = {
hardware-compatibility: [ "1.0" ];
files: (
{
filename = "var-image-swupdate-imx8mp-var-dart.tar.gz";
type = "archive";
compressed = true;
device = "/dev/update";
filesystem = "ext4";
path = "/";
}
);
scripts: (
{
filename = "update.sh";
type = "shellscript";
}
);
};
}
And the following is the aforementioned update.sh bash script: update.sh This script is being used in order to detect the root device and the U-Boot env. type and location (eMMC vs NAND flash) at runtime.
Create a SWUpdate-ready Image¶
There are two common ways to prepare the initial A/B layout on the eMMC:
1) build a recovery SD card and run the installer script, or
2) flash a complete .wic image directly from the host PC.
Option 1: Recovery SD card + install_yocto.sh¶
- Follow steps 1-3 of the Yocto Build Release page.
-
Build a recovery SD card and the var-image-swupdate image as the recovery image
-
Boot the board using the created SD card. See more info here.
- Install the demo image to the eMMC using the install_yocto.sh script with the "-u" parameter.
When called with the "-u" parameter, the install_yocto.sh script creates the double-copy compatible layout as shown above
Option 2: Flash a complete WIC image¶
Build a flashable WIC image¶
As an alternative to the recovery SD card flow above, you can build a complete .wic image based on var-image-swupdate and flash it directly to the target storage.
This recipe is defined in dynamic-layers/swupdate/var-image-swupdate.bb. For mx8-nxp-bsp machines it uses the Wic layout file wic/var-imx-swu-dual-rootfs.wks.in, which creates an image with:
- A reserved boot area at the beginning of the disk, with
imx-bootwritten at the${IMX_BOOT_SEEK}offset - Two ext4 rootfs partitions,
rootfs1androotfs2, for the A/B update layout - One ext4
/datapartition labeleddata
The file currently contains:
part u-boot --source rawcopy --sourceparams="file=imx-boot" --ondisk mmcblk --no-table --align ${IMX_BOOT_SEEK}
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs1 --align 8192 --extra-space 150M
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs2 --align 8192 --extra-space 150M
part /data --ondisk mmcblk --fstype=ext4 --label data --size 10M --align 4096 --extra-space 0
bootloader --ptable msdos
In this layout, Wic copies the same var-image-swupdate root filesystem into both rootfs slots and adds a dedicated /data partition for persistent user/application data.
Change the /data partition size¶
To increase the size of the data partition, modify the --size argument in the Wic file. For example, to change /data from 10 MiB to 512 MiB:
This image includes Variscite's var-expand-partition.service.
On the first boot, var-expand-partition.sh detects the current root disk, checks the partition table with parted, resizes the last partition to 100% of the remaining device, and then runs resize2fs on it.
With the var-imx-swu-dual-rootfs.wks.in layout shown above, the last partition is /data, so /data is automatically expanded on the first boot to use the remaining eMMC space not already used by rootfs1 and rootfs2.
This means the --size setting defines the initial /data size in the flashed image, before /data is grown on the first boot.
If you build a custom image without this service, /data will keep the size defined in the Wic layout, so you must set the final desired size in the .wks file.
The recommended approach is to copy var-imx-swu-dual-rootfs.wks.in to your own layer, update it there, and then point WKS_FILE to the customized file from a var-image-swupdate.bbappend.
Example:
# meta-my-layer/dynamic-layers/swupdate/var-image-swupdate.bbappend
WKS_FILE:mx8-nxp-bsp = "var-imx-swu-dual-rootfs-custom.wks.in"
After changing the Wic file, rebuild var-image-swupdate so Yocto regenerates the .wic image with the new partition layout.
Build the SWUpdate image:
MACHINE=imx8mp-var-dart DISTRO=fsl-imx-xwayland . var-setup-release.sh build_xwayland
bitbake var-image-swupdate
After the build completes, the main artifacts are generated under tmp/deploy/images/imx8mp-var-dart/:
var-image-swupdate-imx8mp-var-dart.rootfs.wicvar-image-swupdate-imx8mp-var-dart.rootfs.wic.zstvar-image-swupdate-imx8mp-var-dart.rootfs.wic.bmap
Flash the WIC image via UMS¶
If the board already boots U-Boot, you can export the eMMC to the host PC with ums and then write the generated .wic image from the host.
On the target U-Boot console:
Note: ${emmc_dev} is the U-Boot environment variable for the eMMC MMC device index. It does not select the A/B rootfs slot. Confirm the ${emmc_dev} value with printenv emmc_dev or mmc list.
On the host PC, write the image to the block device exposed by ums:
sudo bmaptool copy tmp/deploy/images/imx8mp-var-dart/var-image-swupdate-imx8mp-var-dart.rootfs.wic /dev/sdX
For more details about bmaptool, see the Yocto Project Scarthgap documentation:
bmaptool.
Replace sdX with the block device created on the host by the ums command. To exit ums, press Ctrl+C on the U-Boot console.
Flash the WIC image via UUU / mfgtools¶
Variscite provides the var-uuu-installer recipe in recipes-variscite/var-install-packages/var-uuu-installer.bb. It inherits classes/var-uuu-installer.bbclass, which packages the bootloader, the .wic image, the .wic.bmap file, and a ready-to-run uuu_script.
Set the image to be packaged by var-uuu-installer in conf/local.conf:
Then build the UUU package:
MACHINE=imx8mp-var-dart DISTRO=fsl-imx-xwayland . var-setup-release.sh build_xwayland
bitbake var-uuu-installer
The generated package is:
tmp/deploy/images/imx8mp-var-dart/var-uuu-installer-imx8mp-var-dart.tar.zst
Extract it:
tar --use-compress-program=unzstd -xf tmp/deploy/images/imx8mp-var-dart/var-uuu-installer-imx8mp-var-dart.tar.zst -C /tmp
cd /tmp/uuu-installer
The extracted folder contains:
uuu_scriptimx-boot(or similar bootloader artifact)var-image-swupdate-imx8mp-var-dart.rootfs.wicvar-image-swupdate-imx8mp-var-dart.rootfs.wic.bmap
The generated uuu_script boots the board over USB and flashes the bootloader and the .wic image to the eMMC.
Put the board in USB serial download mode and run:
This is the mfgtools/UUU flow for flashing the same .wic layout without requiring a bootable Linux system on the target first.
Generate a Field Update file (.swu image)¶
- Make your changes in ~/var-fsl-yocto
- Edit the sw-description file
- Generate .swu file:
Test SWUpdate¶
- Get the target's IP address using ifconfig
-
Open a web browser on the host and connect to the SWUpdate web server on the target by entering the following in the address bar:
-
On the web page, click "Browse..." and open the .swu image which is located at tmp/deploy/images/imx8mp-var-dart/var-image-swu-imx8mp-var-dart.swu
Known Issues¶
Due to a known issue in libarchive
swupdate may fail decompressing the rootfs.tar.gz if any filename include UTF8 chars.
To let libarchive work without problems, a valid UTF8 locale for LC_CTYPE is required, however the default value is just "C".
From the command line, you can workaround this behavior by running
For the systemd service, in the file
you can add the property
For the sysVinit service, in the file
you can change the line
exec $DAEMON -v -H ${hardware}:1.0 -f /etc/swupdate.cfg $SWUPDATE_EXTRA_ARGS -u "$EXTRA_ARGS" -w "" -p 'reboot' &
to