Issue with Redundant Boot (A/B) Configuration on Verdin iMX8MP BSP 7.4 – Boot Partition Not Switching

Hello Toradex Support Team,

I am working on implementing a redundant (A/B) boot mechanism on the Verdin iMX8MP module using Toradex BSP version 7.4.0.
I am facing issues in correctly switching the boot partitions.


System Details

  • Module: Verdin iMX8MP

  • BSP Version: 7.4.0

  • U-Boot Version: 2024.07 (Toradex BSP)

  • Build System: Yocto (OpenEmbedded)

  • Image: Reference minimal image (customized)

  • Storage: eMMC


Current Partition Layout

On the target, I have the following layout:

mmcblk2 (eMMC):

  • mmcblk2p1 → BOOT_A (48MB)

  • mmcblk2p2 → RFS_A (512MB)

  • mmcblk2p3 → BOOT_B (48MB)

  • mmcblk2p4 → RFS_B (512MB)

mmcblk1 (external storage):

  • rootfsA

  • rootfsB

  • data

Example output from lsblk:

mmcblk2
|- mmcblk2p1 → BOOT_A
|- mmcblk2p2 → RFS_A
|- mmcblk2p3 → BOOT_B
`- mmcblk2p4 → RFS_B


Current Behavior

  • Root filesystem switching works correctly.

  • System alternates between RFS_A and RFS_B as expected.

  • However, BOOT partition is always taken from BOOT_A (mmcblk2p1).

  • BOOT_B (mmcblk2p3) is never selected, even after slot change.

  • Kernel and DTB are always loaded from mmc 2:1.

So only rootfs redundancy is working, but boot partition redundancy is not.


U-Boot Environment

Current bootcmd:

bootcmd=load mmc 2:1 ${loadaddr} Image.gz; unzip ${loadaddr} ${kernel_addr_r}; load mmc 2:1 ${fdt_addr_r} imx8mp-verdin-nonwifi-dev.dtb; booti ${kernel_addr_r} - ${fdt_addr_r}

boot_targets=mmc1 mmc2 dhcp

From this, U-Boot is always loading kernel and DTB from mmc 2:1 (BOOT_A).


Modifications Done

  1. Modified U-Boot in workspace to support redundant boot.

  2. Enabled environment overwrite using:

CONFIG_ENV_ALLOW_OVERWRITE=y

  1. Rebuilt U-Boot and integrated it into Yocto.

  2. Flashed using Toradex Easy Installer / UUU.

  3. Configured A/B rootfs partitions.

  4. Verified rootfs switching works.


Expected Behavior

I expect the system to:

  • Boot from BOOT_A + RFS_A in slot A

  • Boot from BOOT_B + RFS_B in slot B

  • Automatically switch kernel, DTB, and rootfs together

  • Optionally support switching between eMMC boot partitions (boot0/boot1) in future

But currently, only rootfs is switching.


Questions / Clarification Needed

  1. Is additional U-Boot configuration required to enable BOOT_A / BOOT_B switching?

  2. Should I modify the default Toradex distro boot scripts to support A/B boot?

  3. Is it recommended to use U-Boot environment variables (boot_part, root_part, etc.) for this?

  4. Should mmc boot partitions (boot0/boot1) be used instead of user partitions for redundancy?

  5. Is there an official reference implementation for full A/B boot on Verdin iMX8MP BSP 7.4?


Goal

My goal is to implement a robust redundant boot mechanism where:

  • U-Boot, kernel, DTB, and rootfs can all be switched safely

  • System can fall back to the secondary slot if the primary slot fails

  • The mechanism can be used for OTA updates in production


I would appreciate your guidance on the correct and recommended approach for implementing full redundant boot (boot + rootfs) on Verdin iMX8MP with BSP 7.4.

Thank you for your support.

Best regards,
Vrushabh Chandanshive

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


To implement full A/B boot redundancy on Verdin iMX8MP with BSP 7.4.0, you need to modify U-Boot environment variables to dynamically switch both boot and root partitions together.

Understanding the Current Issue

Your current bootcmd is hardcoded to always use partition 1 for boot files(1):

bootcmd=load mmc 2:1 ${loadaddr} Image.gz; unzip ${loadaddr} ${kernel_addr_r}; load mmc 2:1 ${fdt_addr_r} imx8mp-verdin-nonwifi-dev.dtb; booti ${kernel_addr_r} - ${fdt_addr_r}

This explains why only rootfs switching works - the boot partition reference (mmc 2:1) is static(1).

Recommended Solution Using U-Boot Environment Variables

1. Implement Dynamic Boot Partition Selection

You should modify your bootcmd to use environment variables that can switch both boot and root partitions dynamically(1). The key variables to work with are:

  • devnum: Index of the current boot device(1)
  • devtype: Type of the current boot device(1)
  • distro_bootpart: Partition number of the boot device used to load kernel and device tree(1)
  • root_part: Partition number containing the root filesystem(1)

2. Create Custom Boot Variables

Set up environment variables for A/B switching(1):

# For Slot A
setenv boot_part_a 1
setenv root_part_a 2

# For Slot B  
setenv boot_part_b 3
setenv root_part_b 4

# Current active slot variable
setenv active_slot a

3. Modify bootcmd for Dynamic Switching

Replace your hardcoded bootcmd with a dynamic version(1):

setenv bootcmd_dynamic 'if test "${active_slot}" = "a"; then setenv boot_part ${boot_part_a}; setenv root_part ${root_part_a}; else setenv boot_part ${boot_part_b}; setenv root_part ${root_part_b}; fi; load mmc 2:${boot_part} ${loadaddr} Image.gz; unzip ${loadaddr} ${kernel_addr_r}; load mmc 2:${boot_part} ${fdt_addr_r} imx8mp-verdin-nonwifi-dev.dtb; setenv bootargs root=/dev/mmcblk2p${root_part} ${tdxargs}; booti ${kernel_addr_r} - ${fdt_addr_r}'

4. Save Environment Changes

After making these changes, save them permanently(1):

saveenv

Important Considerations

Environment Variable Management

When using saveenv, remember that it saves the entire environment to persistent memory, not just the changed variable(2). This means any dynamically calculated variables (like those set during preboot) will become static(2).

U-Boot fw-utils for Runtime Management

You can use fw_setenv from Linux to switch slots at runtime(3):

# Switch to slot B
fw_setenv active_slot b

# Switch to slot A  
fw_setenv active_slot a

Alternative Approach: Use DistroBoot Variables

Consider leveraging Toradex’s DistroBoot implementation by modifying boot_targets and using the existing devnum and devtype variables(1). This approach works with the standard Toradex boot flow.

Production Recommendations

1. Fallback Mechanism

Implement a fallback mechanism where if the primary slot fails to boot, U-Boot automatically tries the secondary slot.

2. Boot Counter

Consider implementing a boot counter mechanism to prevent infinite boot loops on a failed slot.

3. Secure Boot Compatibility

If you plan to use secure boot in production, ensure your A/B implementation is compatible with Toradex’s secure boot features, which include FIT image signature checking and U-Boot hardening.

Next Steps

  1. Test the dynamic bootcmd approach in your development environment
  2. Implement proper error handling and fallback logic
  3. Consider using the standard DistroBoot flow with modified boot_targets for better integration with Toradex BSP updates
  4. Test OTA update scenarios thoroughly before production deployment

This approach will give you true A/B redundancy for both boot files (kernel, DTB) and rootfs partitions while maintaining compatibility with the Toradex BSP framework.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.