
Implementation Scheme of Linux 4.14 OTA Upgrade Based on RAUC for OKMX8MM
This document aims to provide an Over-The-Air (OTA) upgrade solution based on RAUC (Robust Auto-Update Controller), which is suitable for embedded Linux systems. RAUC is an open-source OTA framework developed by Pengutronix. It is specifically designed for industrial-grade devices and provides secure, reliable, and atomic firmware update capabilities. It can run on multiple platforms, including Linux, FreeRTOS, and bare-metal environments. OTA is a technology for remotely updating the firmware of embedded devices via wireless networks (such as Wi-Fi, 4G, 5G, etc.). It enables functions such as firmware updates, configuration pushes, and security patches without physically accessing the devices.
In this paper, the RAUC-V0.1 version (the official initial version) is taken as an example for deployment and verification on 8mm-linux4.14.78. Currently, RAUC has been updated to version V1.14. Other platforms can select appropriate versions for transplantation according to the kernel version, glib version, and openssl version. This transplantation only supports manual upgrades and manual partition switching. If necessary, automatic upgrades can be achieved by adding environment variables in U-Boot.
Other OTA upgrade tools: SWupdate
Configuration requirements
Note: Only the basic RAUC upgrade functions are described here. For example, streaming online updates are only supported in RAUC-v1.7 and above.
1. Kernel Version:
It has been verified that it can run on kernel versions above Linux 4.14. Lower versions have not been verified yet, but theoretically they can also be used. For kernel versions without systemd service, --disable-service needs to be specified when compiling the RAUC source code.
2. File System:
RAUC has no restrictions on the content of the file system. However, since an A/B system is implemented, the flash should have at least twice the capacity of the file system.
Deployment scheme
1. Install RAUC in the development environment.
~/work/project/rauc$ git clone https://github.com/rauc/rauc ~/work/project/rauc$ cd rauc ~/work/project/rauc$ git checkout v0.1 ~/work/project/rauc$ ./autogen.sh ~/work/project/rauc$ ./configure ~/work/project/rauc$ make
2. Install RAUC on the development board.
Note: Copy the json-glib and json-glib-native libraries to the cross-compiler for cross-compilation purposes
~/work/project/rauc$ git clone https://github.com/rauc/rauc ~/work/project/rauc$ cd rauc ~/work/project/rauc$ git checkout v0.1 ~/work/project/rauc$ ./autogen.sh ~/work/project/rauc$ ./configure --host=aarch64-poky-linux-gcc ~/work/project/rauc$ make
3. Key File
Manually generate a key in the development environment and put it in the source code of the file system. RAUC will verify whether the key of the image is consistent with that of the system when upgrading;
OK8MM-linux-sdk$ openssl genrsa -out autobuilder.key.pem 4096 OK8MM-linux-sdk$ openssl req -new -x509 -key autobuilder.key.pem -out \ autobuilder.cert.pem -days 365 -subj "/CN=AutoBuilder OTA \ Signing Authority/O=YourCompany/C=CN"
Place the generated autobuilder. cert. pem and autobuilder. key. pem key files under the filesystem/etc/rauc/.
4. bundle
Compile the configuration file of the upgrade package
Generate image check code: OK8MM-linux-sdk/images$ sha256sum ./rootfs.ext4de2f256064a0af797747c2b97505dc0b9f3df0de4f489eac731c23ae9ca9cc31
To create a manifest profile:
OK8MM-linux-sdk/bundle$ vim manifest [update] compatible=Forlinx_rauc_8m version=20250801 build=20250808 [image.rootfs] sha256=de2f256064a0af797747c2b97505dc0b9f3df0de4f489eac731c23ae9ca9cc31 size=24117248 filename=rootfs.ext4 Copy the upgrade image to the bundle directory: OK8MM-linux-sdk/bundle$ cp ../images/rootfs.ext4 ./
5. system.conf
The system. conf is the system configuration file of RAUC, which is responsible for configuring the storage, partition, and boot mode; it is the configuration file used in the upgrade process.
The path can be:/etc/rauc/system. conf,/run/rauc/system. conf,/etc/lib/rauc/system. conf; Load in order from the listed directories, using only the first file found.
eg.:
[system] compatible=Forlinx_rauc_8m bootloader=uboot [keyring] path=/etc/rauc/autobuilder.cert.pem [handlers] #system-info=/usr/lib/rauc/info-provider.sh #post-install=/usr/lib/rauc/postinst.sh [slot.rootfs.0] device=/dev/mmcblk2p2 type=ext4 bootname=system0 [slot.rootfs.1] device=/dev/mmcblk2p4 type=ext4 bootname=system1 [artifacts.add-ons] path=/srv/add-ons type=trees [log.install-log] filename=install.log events=install output-format=short
6. Add rauc.service service to the source code
When upgrading rauc, it is necessary to start the service to automatically complete the upgrade operation:
Rauc self-start service: OK8MM-linux-fs$ vim /lib/systemd/system/rauc.service
[Unit] Description=Rauc Update Service Documentation=https://rauc.readthedocs.io After=dbus.service [Service] Type=dbus BusName=de.pengutronix.rauc ExecStart=/usr/bin/rauc --mount=/run/rauc service RuntimeDirectory=rauc MountFlags=slave systemctl enable /lib/systemd/system/rauc.service systemctl daemon-reload
Create a self starting soft connection:
OK8MM-linux-fs$ ln -s lib/systemd/system/rauc.service \
lib/systemd/system/sysinit.target.wants/rauc.service
Create a rauc configuration file under D-bus:
D-bus explanation: mainly used for implementing atomic update control, status monitoring, and system integration;
OK8MM-linux-fs$ vim /usr/share/dbus-1/system-services/de.pengutronix.rauc.service [D-BUS Service] Name=de.pengutronix.rauc Exec=/usr/bin/rauc service User=root SystemdService=rauc.service OK8MM-linux-fs$ vim /etc/dbus-1/system.d/rauc.conf <busconfig> <policy user="root"> <allow own="de.pengutronix.rauc"/> </policy> <policy context="default"> <allow send_destination="de.pengutronix.rauc"/> </policy> </busconfig>
After burning the image, check if the rauc service is started:
root@okmx8mm:~# systemctl status rauc.service ● rauc.service - Rauc Update Service Loaded: loaded (/lib/systemd/system/rauc.service; static; vendor preset: ena> Active: active (running) since Thu 2019-06-20 10:00:14 UTC; 5h 6min ago Docs: https://rauc.readthedocs.io Main PID: 3223 (rauc) Tasks: 3 (limit: 1603) CGroup: /system.slice/rauc.service └─3223 /usr/bin/rauc --mount=/run/rauc service Jun 20 10:00:13 okmx8mm systemd[1]: Starting Rauc Update Service... Jun 20 10:00:14 okmx8mm systemd[1]: Started Rauc Update Service.
7. Compile environment variable reading and writing tools
When upgrading to rauc, the fw_ setenv and fw_ printenv tools are needed, mainly to obtain the uboot environment variable from the file system and determine the current mounted partition
Annotate the Makefile line in uboot: There is a problem with the default cross compilation configuration. After commenting it out, execute the environment variables on the command line and compile directly.
OK8MM-linux-sdk/OK8MM-linux-uboot$ git diff diff --git a/Makefile b/Makefile index 225fa68..923aaf4 100644 --- a/Makefile +++ b/Makefile @@ -338,7 +338,7 @@ LD = $(CROSS_COMPILE)ld.bfd else LD = $(CROSS_COMPILE)ld endif -CC = $(CROSS_COMPILE)gcc +#CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm OK8MM-linux-sdk/OK8MM-linux-uboot$ make envtools CHK include/config/uboot.release CHK include/generated/version_autogenerated.h UPD include/generated/version_autogenerated.h CHK include/generated/timestamp_autogenerated.h UPD include/generated/timestamp_autogenerated.h LD tools/env/built-in.o HOSTCC tools/env/fw_env_main.o HOSTLD tools/env/fw_printenv STRIP tools/env/fw_printenv
Copy fw-printenv to the file system/usr/bin/and make a copy of fw_steenv: cp fw-printenv fw_steenv
8. Create/etc/fw_env.config
The file system reads environment variables by directly reading the emmc address, and the fw-env.config name is fixed and cannot be changed arbitrarily, consistent with the rauc source code.
OK8MM-linux-fs$ vim /etc/fw_env.config /dev/mmcblk2 0x400000 0x1000
9. Compile and update packages
RAUC tool compilation upgrade package: rauc bundle --cert=<certfile|certurl> --key=<keyfile|keyurl> <input-dir> <bundle-name>
eg.:
OK8MM-linux-sdk$ rauc bundle --cert autobuilder.cert.pem --key autobuilder.key.pem \ bundle/ update.raucb OK8MM-linux-sdk$ ls update.raucb update.raucb
10. rauc Test
Test premise: The file system partition has been modified, refer to 8mp:
https://forlinx-book.yuque.com/org-wiki-forlinx-book-vclsg5/ibgvyy/fnmsrhfem740p753?singleDoc# OKMX8MP-Linux 5.4.70-OTA Upgrade Using Extended Partition
root@okmx8mm:~# rauc install /run/media/sda1/update-2025.8.4.raucb -d Domains: ‘rauc' (rauc:4425): rauc-DEBUG: install started (rauc:4425): rauc-DEBUG: input bundle: /run/media/sda1/update-2025.8.4.raucb trying to contact rauc service rauc-Message: installing /run/media/sda1/update-2025.8.4.raucb: installing [20155.868460] EXT4-fs (mmcblk2p4): VFS: Can't find ext4 filesystem [20271.742672] EXT4-fs (mmcblk2p4): mounted filesystem with ordered data mode. Opts: (null) rauc-Message: installing /run/media/sda1/update-2025.8.4.raucb: idle installing `/run/media/sda1/update-2025.8.4.raucb` succeeded root@okmx8mm:~# sync
Manually switch boot partition: enter the uboot command line or use the fw_ setenv tool to modify the boot partition
u-boot=> setenv mmcdev 3 u-boot=> setenv mmcroot /dev/mmcblk2p4 rootwait rw u-boot=> save u-boot=> reset
Problems
1. System time issue
root@okmx8mm:~# rauc install /run/media/sda1/update-2025.8.4.raucb -d Domains: ‘rauc' (rauc:4378): rauc-DEBUG: install started (rauc:4378): rauc-DEBUG: input bundle: /run/media/sda1/update-2025.8.4.raucb trying to contact rauc service rauc-Message: installing /run/media/sda1/update-2025.8.4.raucb: installing installing `/run/media/sda1/update-2025.8.4.raucb` failed root@okmx8mm:~# journalctl -u rauc.service -n 100 --no-pager Jun 20 15:26:40 okmx8mm rauc[3223]: installing /run/media/sda1/update-2025.8.4.raucb: started Jun 20 15:26:40 okmx8mm rauc[3223]: Mounting bundle '/run/media/sda1/update-2025.8.4.raucb' to '/run/rauc/bundle' Jun 20 15:26:40 okmx8mm rauc[3223]: installing /run/media/sda1/update-2025.8.4.raucb: Checking and mounting bundle... Jun 20 15:26:40 okmx8mm rauc[3223]: Reading bundle: /run/media/sda1/update-2025.8.4.raucb Jun 20 15:26:40 okmx8mm rauc[3223]: Verifying bundle... Jun 20 15:26:40 okmx8mm rauc[3223]: umount: /run/rauc/bundle: not mounted. Jun 20 15:26:40 okmx8mm rauc[3223]: Failed mounting bundle: signature verification failed: Verify error:certificate is not yet valid Jun 20 15:26:40 okmx8mm rauc[3223]: installing /run/media/sda1/update-2025.8.4.raucb: Failed mounting bundle: signature verification failed: Verify error:certificate is not yet valid Jun 20 15:26:40 okmx8mm rauc[3223]: installing /run/media/sda1/update-2025.8.4.raucb: finished Jun 20 15:26:40 okmx8mm rauc[3223]: installing `/run/media/sda1/update-2025.8.4.raucb` failed: 1
Solutions:
root@okmx8mm:~# date -s 20250824 root@okmx8mm:~# rauc install /run/media/sda1/update-2025.8.4.raucb -d Domains: ‘rauc' (rauc:4425): rauc-DEBUG: install started (rauc:4425): rauc-DEBUG: input bundle: /run/media/sda1/update-2025.8.4.raucb trying to contact rauc service rauc-Message: installing /run/media/sda1/update-2025.8.4.raucb: installing [20155.868460] EXT4-fs (mmcblk2p4): VFS: Can't find ext4 filesystem [20271.742672] EXT4-fs (mmcblk2p4): mounted filesystem with ordered data mode. Opts: (null) rauc-Message: installing /run/media/sda1/update-2025.8.4.raucb: idle installing `/run/media/sda1/update-2025.8.4.raucb` succeeded
2. fw-print compilation error
forlinx@DESKTOP-JKUAQGE:~/work/ok8mm/OK8MM-linux-sdk/prj/nxp-uboot/uboot-imx$ make envtools CHK include/config/uboot.release CHK include/generated/version_autogenerated.h CHK include/generated/timestamp_autogenerated.h UPD include/generated/timestamp_autogenerated.h LD tools/env/built-in.o HOSTCC tools/env/crc32.o In file included from tools/env/crc32.c:1:0: tools/env/crc32.c: 12:10 PM: fatal error: arpa/inet.h: No such file or directory #include^~~~~~~~~~~~~ compilation terminated. scripts/Makefile.host:116: recipe for target 'tools/env/crc32.o' failed make[1]: *** [tools/env/crc32.o] Error 1 Makefile:1504: recipe for target 'envtools' failed make: *** [envtools] Error 2
Solutions:
forlinx@DESKTOP-JKUAQGE:~/work/ok8mm/OK8MM-linux-sdk/prj/nxp-uboot/uboot-imx$ git diff diff --git a/Makefile b/Makefile index 225fa6828cb..923aaf484e9 100644 --- a/Makefile +++ b/Makefile @@ -338,7 +338,7 @@ LD = $(CROSS_COMPILE)ld.bfd else LD = $(CROSS_COMPILE)ld endif -CC = $(CROSS_COMPILE)gcc +#CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm
3. Env configuration file issue
Cannot parse config file '/etc/fw_env.config': No such file or directoryAug 03 00:08:16 okmx8mm rauc[3189]: Error: environment not initializedAug 03 00:08:16 okmx8mm rauc[3189]: fw_setenv failed: Child process exited with code 1Aug 03 00:08:16 okmx8mm rauc[3189]: failed marking as badAug 03 00:08:17 okmx8mm rauc[3189]: Handler error: Failed marking slot rootfs.1 non-bootableAug 03 00:08:17 okmx8mm rauc[3189]: installing /run/media/sda1/update-2015.04-1.raucb: Handler error: Failed marking slot rootfs.1 non-bootableAug 03 00:08:17 okmx8mm rauc[3189]: installing /run/media/sda1/update-2015.04-1.raucb: finishedAug 03 00:08:17 okmx8mm rauc[3189]: installing `/run/media/sda1/update-2015.04-1.raucb` failed: 1
Solutions:
Refer to Chapter 3-8 of this article
4. The file system cannot read the correct environment variables
There is an issue with the address of the environment variable being read. Simply add the relevant configuration to the uboot source code;
OK8MM-linux-uboot$ git diff configs/imx8mm_evk_defconfig diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig index b557f55..8f3c92d 100644 --- a/configs/imx8mm_evk_defconfig +++ b/configs/imx8mm_evk_defconfig @@ -20,6 +20,10 @@ CONFIG_CMD_FAT=y CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8mm-evk" CONFIG_DEFAULT_FDT_FILE="ok8mm-evk.dtb" CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_SYS_REDUNDAND_ENVIRONMENT
Design List
1. File List
rootfs: etc/dbus-1/system.d/rauc.conf etc/fw_env.config etc/init.d/Init.sh etc/rauc/ lib/systemd/system/rauc.service lib/systemd/system/sysinit.target.wants/rauc.service usr/bin/fw_printenv usr/bin/fw_setenv usr/bin/mksquashfs usr/bin/rauc usr/bin/unsquashfs usr/share/dbus-1/system-services/de.pengutronix.rauc.service uboot: Makefile board/freescale/common/mmc.c board/freescale/imx8mm_evk/imx8mm_evk.c configs/imx8mm_evk_defconfig tools/env/fw_env.c
2. Function Description
root@okmx8mm:~# rauc --help Usage: rauc [OPTION?] <COMMAND> Options: -c, --conf=FILENAME config file --cert=PEMFILE cert file --key=PEMFILE key file --mount=PATH mount prefix --handler-args=ARGS extra handler arguments -d, --debug enable debug output --version display version -h, --help List of rauc commands: bundle Create a bundle checksum Update a manifest with checksums (and optionally sign it) install Install a bundle info Show file information status Show status
Related link:
RAUC official website: https://rauc.readthedocs.io/en/latest/index.html
Source code: https://github.com/rauc/rauc