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




Dear friends, we have created an exclusive embedded technical exchange group on Facebook, where our experts share the latest technological trends and practical skills. Join us and grow together!