Skip to content

Commit cc8872b

Browse files
committed
meta-rauc-nxp: added support for an A/B update scheme for the boot partitions via the rauc-ab-bootrootfs distro feature
The code is written in a way that is completely backward compatible with the rootfs only solution. It would be more elegant to have it in another layer. Please read the extensively detailed README.frdm-imx93.rst file for more details. Signed-off-by: Ron Munitz <ron@thepscg.com>
1 parent 73e4b7e commit cc8872b

11 files changed

Lines changed: 347 additions & 26 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
This README file has specific instructions for the NXP FRDM-IMX93 development board.
2+
It is separated from the other README, to allow for more specific instructions, and overrides, that can be useful for demonstrating additional RAUC constructs.
3+
The author has separated the effort to avoid touching the previous authors architecture, and he would be glad to rearchitect the layer.
4+
5+
The file only specifies things that are not already specified in the README.rst file, and keeps the section numbers identical to those in that file,
6+
making the gaps here intentional.
7+
We use the exact same instructions and style. Obviously, you would better add what you need in your respective distro file, and not in local.conf.
8+
9+
The main construct added in this example is a dual (A/B) boot/rootfs partition update scheme, where the disk layout is as follows:
10+
11+
* p1 - BOOT_A
12+
* p2 - BOOT_B
13+
* p3 - RES (e.g., for rescue or recovery image)
14+
* p5 - ROOTFS_A
15+
* p6 - ROOTFS_B
16+
* p7 - DATA
17+
18+
This of course means another kickstart file needs to be implemented, but it also means, that another image class, for getting the required boot files (i.e. what U-Boot expects
19+
to be on a vfat partition) needs to be implemented, so we can populate it and add it to the ``IMAGE_FSTYPES``.
20+
21+
We will introduce a new ``DISTRO_FEATURE``, with the amazing (sorry not sorry) name ``rauc-ab-bootrootfs`` and add all of the above only if it exists, by adding it to the overrides.
22+
This way, the existing recipe code will remain untouched (I would separate it, but I can't test it, and I just wanted to give this example).
23+
24+
**Note** The implementation could be more elegant if we just used another layer or did not bother about the one boot/2rootfs scheme that is in the overall meta-rauc-community repo.
25+
However, to keep things simple for comparison, I made the extra effort to have the previous behavior (one boot, 2 rootfs partitions) the default one.
26+
In the dual boot/rootfs solution (i.e. the ``rauc-ab-bootrootfs`` override), everything is identical except for the partition scheme with the following exceptions:
27+
* No autogrowing the data partition - and renaming the relevant recipe to a common include. Otherwise more work needs to be done
28+
* Less hardcoding otherwise
29+
* U-Boot is fully aware of which device it is running from, and not hardcoded to the sdcard.
30+
* This can and should be done for the rest of the components - but to keep it very similar to the previous version prior to introducing this feature, the sdcard is assumed.
31+
This is the first thing I would change if I have time, and it may happen soon enough (hopefully soon enough so you don't even see this line)
32+
33+
34+
II. Build NXP Demo System
35+
===============================================
36+
37+
For FRDM-IMX93 set in local.conf::
38+
39+
MACHINE = "imx93frdm"
40+
INIT_MANAGER = "systemd"
41+
ACCEPT_FSL_EULA = "1"
42+
43+
#----------------------------------------------
44+
# RAUC example. It is strongly recommended to
45+
# not put these things in your local.conf
46+
# (it is however good for explanations)
47+
#----------------------------------------------
48+
# Add RAUC support
49+
DISTRO_FEATURES:append = " rauc"
50+
IMAGE_FSTYPES:append = " ext4"
51+
IMAGE_BOOT_FILES:append = " boot.scr"
52+
WKS_FILE:imx93frdm = "dual-imx-boot-bootpart.wks.in"
53+
54+
# Allow selection of the bundle rather than hardcoding it
55+
BUNDLE_IMAGE_NAME ?= "core-image-base"
56+
57+
# Add RAUC support for a dual boot, dual rootfs partition scheme
58+
# First let's add a little cheatcode: make up a little machine override, so that we son't need to use bb.utils.contains more than this time
59+
MACHINEOVERRIDES:append:imx93frdm = "${@bb.utils.contains('DISTRO_FEATURES', 'rauc-ab-bootrootfs', ':rauc-ab-bootrootfs', '', d)}"
60+
DISTRO_FEATURES:append = " rauc-ab-bootrootfs"
61+
BOOT_PARTITION_SIZE_MIB:rauc-ab-bootrootfs = "64"
62+
RES_PARTITION_SIZE_MIB:rauc-ab-bootrootfs = "10"
63+
DATA_PARTITION_SIZE_MIB:rauc-ab-bootrootfs = "100"
64+
IMAGE_CLASSES:append:rauc-ab-bootrootfs = " boot-vfat-image"
65+
IMAGE_FSTYPES:append:rauc-ab-bootrootfs = " boot.vfat"
66+
WKS_FILE:rauc-ab-bootrootfs = "imx-2boot-res-2rootfs-data.wks.in"
67+
68+
Build your bundle. It will also build your your respective wic image::
69+
70+
$ bitbake update-bundle
71+
72+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
do_image_boot_vfat[depends] += "mtools-native:do_populate_sysroot dosfstools-native:do_populate_sysroot"
2+
do_image_boot_vfat[vardepsexclude] += "DATETIME"
3+
4+
IMAGE_CMD:boot.vfat () {
5+
# datetime: compute here to avoid non determinism at the recipe level
6+
local datetime=$(date +%Y%m%d%H%M%S)
7+
local outfile=${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}-${datetime}.boot.vfat
8+
local linkfile=${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.boot.vfat
9+
10+
# Remove old timestamped files
11+
rm -f ${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}-*.boot.vfat
12+
13+
dd if=/dev/zero of=$outfile bs=1M count=64
14+
mkfs.vfat $outfile
15+
16+
for entry in ${IMAGE_BOOT_FILES}; do
17+
src=$(echo $entry | cut -d';' -f1)
18+
dst=$(echo $entry | cut -d';' -f2)
19+
dst=${dst:-$src}
20+
if [ -f ${DEPLOY_DIR_IMAGE}/$src ]; then
21+
mcopy -i $outfile -s ${DEPLOY_DIR_IMAGE}/$src ::/$dst
22+
else
23+
bbwarn "$src does not exist although it is specified in your IMAGE_BOOT_FILES variable"
24+
fi
25+
done
26+
27+
cd ${IMGDEPLOYDIR}
28+
ln -sf ${IMAGE_BASENAME}-${MACHINE}-${datetime}.boot.vfat $linkfile
29+
}
30+
31+
#
32+
# Testing tip:
33+
# Allow an (optional!) rfile.txt entry at IMGDEPLOYDIR - one can modify it prior to the build, to see a change in a single file, on the boot partition, and it should be super quick
34+
# e.g., cf. modifying a possibly huge rootfs
35+
# Then, for testing one could do something like
36+
# date > tmp/deploy/images/maytdolx/bootpart.testinfo && bitbake maytdolx-bundle
37+
# Then, because it is an intentional "hack" (to build fast / and not change anything if we don't do it explicitly) one would do, to force a rebuild of the wic (unnecessary, but to to sync the states)
38+
# and the filesystem, and therefore the bundle as follows:
39+
#
40+
# bitbake maytdolx-image -C image_boot_vfat
41+
# bitbake maytdolx-image
42+
#
43+
# You can of course use *image-noalgo with the aforementioned instructions to build the noalgo image.
44+
#
45+
# If you are interested in doing these tests, uncomment the next line, and then you could mount the boot partition upon boot, and see the works when you will have flashed the image or update bundle
46+
#
47+
# IMAGE_BOOT_FILES:append = " bootpart.testinfo"
48+
#
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
test -n "${BOOT_ORDER}" || env set BOOT_ORDER "A B"
2+
test -n "${BOOT_A_LEFT}" || env set BOOT_A_LEFT 3
3+
test -n "${BOOT_B_LEFT}" || env set BOOT_B_LEFT 3
4+
5+
env set boot_pno
6+
env set rootfs_pno;
7+
env set rauc_slot
8+
9+
echo "[+] Booting from mmc device: $mmcdev"
10+
11+
for BOOT_SLOT in "${BOOT_ORDER}"; do
12+
if test "x${rootfs_pno}" != "x"; then
13+
# stop checking after selecting a slot
14+
15+
elif test "x${BOOT_SLOT}" = "xA"; then
16+
if itest ${BOOT_A_LEFT} -gt 0; then
17+
setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1
18+
echo "Booting RAUC slot A"
19+
20+
setenv rootfs_pno 5
21+
setenv boot_pno 1
22+
setenv rauc_slot "A"
23+
fi
24+
25+
elif test "x${BOOT_SLOT}" = "xB"; then
26+
if itest ${BOOT_B_LEFT} -gt 0; then
27+
setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1
28+
echo "Booting RAUC slot B"
29+
30+
setenv rootfs_pno 6
31+
setenv boot_pno 2
32+
setenv rauc_slot "B"
33+
fi
34+
fi
35+
done
36+
37+
38+
if test -n "${rootfs_pno}"; then
39+
setenv mmcpart $boot_pno;
40+
saveenv
41+
else
42+
echo "No valid RAUC slot found. Resetting attempts to 3"
43+
setenv BOOT_A_LEFT 3
44+
setenv BOOT_B_LEFT 3
45+
saveenv
46+
reset
47+
fi
48+
49+
if itest $mmcdev -eq 1 ; then
50+
echo "[+] Will now boot RAUC slot $rauc_slot from sdcard"
51+
elif itest $mmcdev -eq 0 ; then
52+
echo "[+] Will now boot RAUC slot $rauc_slot from eMMC"
53+
else
54+
echo "***ERROR: Will ignore mmc device $mmcdev"
55+
reset
56+
fi
57+
58+
if mmc dev $mmcdev; then
59+
run sr_ir_v2_cmd
60+
mmc dev $mmcdev
61+
setenv devtype mmc
62+
setenv devnum $mmcdev
63+
setenv distro_bootpart $boot_pno
64+
run scan_dev_for_efi
65+
setenv mmcroot /dev/mmcblk${mmcdev}p${rootfs_pno} rootwait rw rauc.slot=${rauc_slot} rauc_example_mode=rauc-ab-bootrootfs
66+
if fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile} ; then
67+
if fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image} ; then
68+
setenv bootargs ${jh_clk} ${mcore_clk} console=${console} root=${mmcroot}
69+
booti ${loadaddr} - ${fdt_addr_r}
70+
else
71+
echo "***ERROR: Failed to boot the Linux kernel"
72+
fi
73+
else
74+
echo "***ERROR: Failed to load the device tree blob $fdtfile"
75+
fi
76+
else
77+
echo "***Could not find mmc device $mmcdev"
78+
reset
79+
fi
80+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/dev/root / auto defaults 1 1
2+
proc /proc proc defaults 0 0
3+
devpts /dev/pts devpts mode=0620,ptmxmode=0666,gid=5 0 0
4+
tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0
5+
6+
/dev/mmcblk1p7 /data ext4 defaults 0 0

meta-rauc-nxp/recipes-core/bundles/update-bundle.bb

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,45 @@ DESCRIPTION = "RAUC bundle generator"
22

33
inherit bundle
44

5+
# Allow selection of the bundle rather than hardcoding it
6+
BUNDLE_IMAGE_NAME ?= "core-image-base"
7+
58
RAUC_BUNDLE_FORMAT = "verity"
69

710
RAUC_BUNDLE_COMPATIBLE = "${MACHINE}"
8-
RAUC_BUNDLE_VERSION = "v20240627"
11+
RAUC_BUNDLE_VERSION = "v20260328"
912
RAUC_BUNDLE_DESCRIPTION = "RAUC demonstration bundle"
1013

1114
RAUC_BUNDLE_SLOTS = "rootfs"
12-
RAUC_SLOT_rootfs = "core-image-base"
15+
RAUC_SLOT_rootfs = "${BUNDLE_IMAGE_NAME}"
1316
RAUC_SLOT_rootfs[fstype] = "ext4"
1417

1518
RAUC_KEY_FILE ?= "${THISDIR}/files/development-1.key.pem"
1619
RAUC_CERT_FILE ?= "${THISDIR}/files/development-1.cert.pem"
20+
21+
#---------------------------------------------------
22+
# Everything here and below is a conditional support
23+
# for having dual boot partition as well.
24+
#---------------------------------------------------
25+
RAUC_BUNDLE_SLOTS:append:rauc-ab-bootrootfs = " boot"
26+
RAUC_SLOT_boot:rauc-ab-bootrootfs = "${BUNDLE_IMAGE_NAME}"
27+
28+
#
29+
# Dynamic file naming based on the overrides
30+
# The only reason for this function is to keep the previous behavior working for the other iMX products. It would be much more elegant to have another layer.
31+
# It is not possible to both use the dictionary and an override together (e.g. as in RAUC_SLOT_boot:... and RAUC_BUNDLE_SLOTS:... above.
32+
#
33+
python () {
34+
# Do something like
35+
# RAUC_SLOT_boot:rauc-ab-bootrootfs[fstype] = "boot.vfat"
36+
# RAUC_SLOT_boot:rauc-ab-bootrootfs[file] = "${BUNDLE_IMAGE_NAME}-${MACHINE}.boot.vfat"
37+
# But legally
38+
overrides = d.getVar('OVERRIDES').split(':')
39+
if 'rauc-ab-bootrootfs' not in overrides:
40+
return
41+
42+
machine = d.getVar('MACHINE')
43+
img = d.getVar('BUNDLE_IMAGE_NAME')
44+
d.setVarFlag('RAUC_SLOT_boot', 'fstype', 'boot.vfat')
45+
d.setVarFlag('RAUC_SLOT_boot', 'file', f'{img}-{machine}.boot.vfat')
46+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
##################################################################################
2+
# RAUC system conf compatible with the community partition layout
3+
# and with the community writing to sdcard.
4+
# To write to the eMMC, e.g. in FRDM-IMX93, use mmcblk0.
5+
# TODO: if anyone cares, add a @@MMCDEVICE@@ literal and sed it like the MACHINE
6+
# I might do it after proving "backward compatibility" to the current meta-rauc-community project
7+
##################################################################################
8+
[system]
9+
compatible=@@MACHINE@@
10+
bootloader=uboot
11+
data-directory=/data/
12+
13+
[keyring]
14+
path=/etc/rauc/ca.cert.pem
15+
16+
# ----------------------------------------------------------------------
17+
# SLOT A
18+
# ----------------------------------------------------------------------
19+
[slot.rootfs.0]
20+
device=/dev/mmcblk1p5
21+
type=ext4
22+
bootname=A
23+
24+
[slot.boot.0]
25+
device=/dev/mmcblk1p1
26+
type=vfat
27+
parent=rootfs.0
28+
29+
# ----------------------------------------------------------------------
30+
# SLOT B
31+
# ----------------------------------------------------------------------
32+
[slot.rootfs.1]
33+
device=/dev/mmcblk1p6
34+
type=ext4
35+
bootname=B
36+
37+
[slot.boot.1]
38+
device=/dev/mmcblk1p2
39+
type=vfat
40+
parent=rootfs.1
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
2+
3+
SRC_URI:append := " \
4+
file://rauc-grow-data-partition.service \
5+
file://grow-data-partition.sh \
6+
"
7+
8+
RDEPENDS:${PN} += "u-boot-fw-utils u-boot-imx-env"
9+
DEPENDS += "u-boot"
10+
11+
inherit systemd
12+
13+
SYSTEMD_PACKAGES += "${PN}-grow-data-part"
14+
SYSTEMD_SERVICE:${PN}-grow-data-part = "rauc-grow-data-partition.service"
15+
16+
PACKAGES += "rauc-grow-data-part"
17+
18+
RDEPENDS:${PN}-grow-data-part += "parted e2fsprogs-resize2fs gptfdisk"
19+
20+
do_install:append() {
21+
install -d ${D}${systemd_unitdir}/system/
22+
install -m 0644 ${WORKDIR}/rauc-grow-data-partition.service ${D}${systemd_unitdir}/system/
23+
24+
install -d ${D}/${bindir}
25+
install -m 0755 ${WORKDIR}/grow-data-partition.sh ${D}/${bindir}
26+
}
Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
11
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
22

3-
SRC_URI:append := " \
4-
file://rauc-grow-data-partition.service \
5-
file://grow-data-partition.sh \
6-
"
7-
8-
RDEPENDS:${PN} += "u-boot-fw-utils u-boot-imx-env"
9-
DEPENDS += "u-boot"
10-
11-
inherit systemd
12-
13-
SYSTEMD_PACKAGES += "${PN}-grow-data-part"
14-
SYSTEMD_SERVICE:${PN}-grow-data-part = "rauc-grow-data-partition.service"
15-
16-
PACKAGES += "rauc-grow-data-part"
17-
18-
RDEPENDS:${PN}-grow-data-part += "parted e2fsprogs-resize2fs gptfdisk"
19-
20-
do_install:append() {
21-
install -d ${D}${systemd_unitdir}/system/
22-
install -m 0644 ${WORKDIR}/rauc-grow-data-partition.service ${D}${systemd_unitdir}/system/
23-
24-
install -d ${D}/${bindir}
25-
install -m 0755 ${WORKDIR}/grow-data-partition.sh ${D}/${bindir}
26-
}
3+
# For backward compatability, only include the grow-partition logic if 'rauc-ab-bootrootfs' is NOT in OVERRIDES
4+
# The .inc file is identical to the previous contents of this .bbappend file
5+
include ${@bb.utils.contains('OVERRIDES', 'rauc-ab-bootrootfs', '', 'rauc-grow-partition.inc', d)}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/dev/mmcblk0p1
2+
/dev/mmcblk0p2
3+
/dev/mmcblk0p3
4+
/dev/mmcblk0p5
5+
/dev/mmcblk0p6
6+
/dev/mmcblk1p1
7+
/dev/mmcblk1p2
8+
/dev/mmcblk1p3
9+
/dev/mmcblk1p5
10+
/dev/mmcblk1p6

meta-rauc-nxp/recipes-core/udev/udev-extraconf_%.bbappend

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,12 @@ SRC_URI:append:cubox-i = " file://cubox-i-rauc.rules"
44
do_install:append:cubox-i() {
55
install -m 0644 ${WORKDIR}/cubox-i-rauc.rules ${D}${sysconfdir}/udev/mount.ignorelist.d/
66
}
7+
8+
9+
FILESEXTRAPATHS:prepend:rauc-ab-bootrootfs := "${THISDIR}/files:"
10+
SRC_URI:append:rauc-ab-bootrootfs = " file://rauc-ab-bootrootfs.rules"
11+
12+
do_install:append:rauc-ab-bootrootfs() {
13+
install -m 0644 ${WORKDIR}/rauc-ab-bootrootfs.rules ${D}${sysconfdir}/udev/mount.ignorelist.d/
14+
}
15+

0 commit comments

Comments
 (0)