Mender A/B Updates with Separate Kernel and Rootfs Partitions on Yocto

Hello everyone,

I’m currently working on a Yocto project on the Scarthgap branch, setting up OTA updates using Mender. By default, Mender proposes the following partitioning scheme:

Partition Usage Size Variable Typical Contents
1 (boot) Bootloader MENDER_BOOT_PART_SIZE_MB U-Boot, EFI
2 (A) Rootfs A auto (depends on total available) Kernel, Rootfs, DTB
3 (B) Rootfs B auto (depends on total available) Kernel, Rootfs, DTB (rollback)
4 (data) Data MENDER_DATA_PART_SIZE_MB Persistent data

However, I would like to have a partitioning scheme that isolates the kernel from the rootfs, while still keeping the A/B layout for atomic updates and rollback for both kernel and rootfs:

Partition Usage Size Variable Typical Contents
1 (boot) Bootloader MENDER_BOOT_PART_SIZE_MB U-Boot, EFI
2 (A) Kernel A auto (depends on total available) Kernel, DTB
3 (B) Kernel B auto (depends on total available) Kernel, DTB (rollback)
4 (A) Rootfs A auto (depends on total available) Rootfs
5 (B) Rootfs B auto (depends on total available) Rootfs (rollback)
6 (data) Data MENDER_DATA_PART_SIZE_MB Persistent data

The problem is, I don’t know how to proceed. Does Mender support this setup? What would be the recommended approach? Has anyone done this before? I haven’t been able to find references on this.

I was thinking about using a custom .wic image and then integrating it with Mender and the bootloader. I made a first attempt with the following files:

.bbappend

# meta-my-layer/meta-wic/recipes-core/images/core-image-minimal.bbappend

IMAGE_FSTYPES += "wic wic.bz2 sdimg"

# Check the wks file name
WKS_FILE = "custom-qemuarm64.wks.in"
WKS_FILE_DEPENDS += "virtual/kernel"

# These variables must match the exact labels in your .wks.in
IMAGE_BOOT_FILES_label-KERNEL_A = "Image qemuarm64.dtb"
IMAGE_BOOT_FILES_label-KERNEL_B = "Image qemuarm64.dtb"

# Generic EFI bootloader for QEMU
IMAGE_BOOT_FILES = "grub-efi-bootaa64.efi"

custom-qemuarm64.wks.in

# core-image-minimal-qemuarm64.wks.in
# GPT partition table for QEMU ARM64 with A/B kernel and rootfs

bootloader --ptable gpt --append="rootwait rootfstype=ext4"

# Boot partition (U-Boot)
part /boot --source bootimg-partition --ondisk vda --fstype=vfat --label boot --active --size 128

# Kernel A
part /bootA --source bootimg-partition --fstype=vfat --label kernelA --align 1024 --size 128

# Kernel B
part /bootB --source bootimg-partition --fstype=vfat --label kernelB --align 1024 --size 128

# Rootfs A
part / --source rootfs --fstype=ext4 --label rootA --align 1024 --size 2048

# Rootfs B
part / --source rootfs --fstype=ext4 --label rootB --align 1024 --size 2048

# Persistent data
part /data --fstype=ext4 --label data --align 1024 --size 256

The problem with this attempt is that the bootloader ends up in my kernel partitions instead of just the Image and DTB.

If anyone has pointers or examples on how to set up a separated A/B kernel + rootfs layout with Mender, that would be greatly appreciated!

Hi @Stan,

As far as I know, there is no public implementation of such a setup yet, unfortunately. So if you’re working on it, I’m happy to help with it and polish for inclusion.

As a starting point, I would probably pick meta-mender-community/kas/demos at wic · TheYoctoJester/meta-mender-community · GitHub, where I have an example to use a fully custom wks file instead of having it automatically created as part of the mender-image approach.

This way you get full control, which should enable you to create such a partition setup.

Greetz,
Josef

Hi Josef,

Thanks a lot for your answer and the pointer — I’ll definitely dig deeper in that direction!

In the meantime, I wanted to check if there’s a temporary approach I could use:
Would it be possible to update just the kernel (which currently resides under /boot inside the rootfs) using a single-file update module?
I was thinking about deploying the new kernel that way and then triggering a reboot to apply it.

If so, would it still be possible to retain rollback support in case the new kernel fails to boot?
And if that’s achievable, should I handle this logic through a custom state script, or is there a recommended Mender mechanism for triggering such a controlled reboot with rollback capability?

Thanks again for your help!

Best,
Stan