Enabling A/B redundancy for rootfs


I’m developing for the Xavier and I’m looking into enabling OTA updates using L4T’s built-in A/B redundancy functionality. While I can see how I would go about creating a BUP for updating the various bootloader partitions and the kernel partitions, I’m not seeing a way to go about enabling redundancy for the rootfs partition (i.e. the APP partition). I can hack something together where I can flash two partitions (APP and APP_b), then change the rootdev cmdline parameter of kernel-dtb: for _a, I can set rootdev to point to mmcblk0p1, and for _b, I can set rootdev to point to mmcblk0p2. However, I don’t see how this would work with BUPs given that the update engine doesn’t seem to allow for separate partition data for _a and _b on the same partition name.

Is there an officially supported way to get rootfs A/B updates using, e.g. the BUP?


hello mattbow,

according to Bootloader Update and Redundancy, it’s an update process for a safe bootloader update.
also, the file system redundancy is disabled by default.

may I know which JetPack release you’re working with.

I’m using the latest, JetPack 4.2.2.

I’ve successfully gotten the BUP working for kernel and bootloader updates, but like you said, the L4T documentation mentions that NVIDIA potentially has a method of getting rootfs OTA updates working as well.

hello mattbow,

please have implementation to enable A/B redundancy for rootfs.
you’ll also access the cboot sources from L4T Sources package.

here are brief steps for your reference,

  1. Modify the partition layout xml, add APP_b immediately after APP partition. you should also set half of original APP size to both new partitions size.
  2. Add define config like CONFIG_ENABLE_A_B_ROOTFS=1 as below
  3. Add a function similar to “add_boot_slot_suffix()” (that adds “boot.slot_suffix=…” to command line). Retrieve current command line settings, and change rootfs to active rootfs if necessary.
    for example,
    the default is
    root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4
    if active is B, change it to
    root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4
    3.1) you might call A/B API tegrabl_a_b_get_active_slot(NULL, uint32_t *active_slot) to get current active slot number.
    3.2) please make sure new code are guarded by CONFIG_ENABLE_A_B_ROOTFS

Thanks very much for the info! I probably won’t have time to test this in depth this month, but I will report back in early October to see if I run into any issues. Based on my poking around the CBoot source code, that seems like the best approach.

Hi Jerry,

May I know TX2 (jetpack 4.2) works with this methos also? I mean A/B redundancy for rootfs.
Besides, Cboot for TX2 R32.1 is released?


1 Like

hello allen.yan,

  1. we did not testing A/B redundancy for rootfs.
  2. I also did not found Cboot package for TX2 R32.1, so it’s not ready for release.

Hello, I wonder if would be possible to have such A/B rootfs redundancy on Nvidia Xavier when using cboot_src_t19x_32.2.3
I wasn’t able to find the partition layout xml nor any reference to CONFIG_ENABLE_A_B_ROOTFS in CBoot.
Thank you

@JerryChang do you have any update about this topic “A/B redundancy for rootfs” ?

hello MarukoBG,

please check latest cboot sources release package from download center.
you might also refer to post #4 to have implementation, thanks

thank you for the prompt answer.
I wasn’t able to find the partition layout XML nor any reference to CONFIG_ENABLE_A_B_ROOTFS in CBoot.
Could you please clarify what did you mean?
Thank you

hello MarukoBG,

it’s because you will need to have implementation to enable A/B redundancy for root file system.
please add a define config in l4t.mk file; for example, CONFIG_ENABLE_A_B_ROOTFS .

I added CONFIG_ENABLE_A_B_ROOTFS to l4t.mk as you said


However I don’t understand what could be the impact of this setting in the CBoot because there is no evidence of its usage in the CBoot sources

bootloader/partner/t18x/cboot/platform/t194/l4t.mk:GLOBAL_DEFINES += CONFIG_ENABLE_A_B_ROOTFS=1

Would you be so kind to provide an example or a better explanation of how to have implementation to enable A/B redundancy for root file system?

Maybe is a typo, because I see the following configuration setting that is very likely what you meant.


Thank you

hello MarukoBG,

because root file system A/B redundancy did not enabled by default,
you’ll need to create a define config and also have your own functional implementations.
for example, you may refer to add_boot_slot_suffix() function which add boot.slot_suffix=… to command line.

static int add_boot_slot_suffix(char *cmdline, int len, char *param, void *priv){...}

hello @JerryChang,
how can I add a second partition in order to have a rootfs clone on the system?

I’d like to split the partition #1 (mmcblk0p1) in two (mmcblk0p1+mmcblk0p2)

$ sudo gdisk -l /dev/mmcblk0

Found valid GPT with protective MBR; using GPT.
Disk /dev/mmcblk0: 61079552 sectors, 29.1 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 5ED5E658-932F-4766-92C2-952C5E9A3B44
Partition table holds up to 42 entries
Main partition table begins at sector 2 and ends at sector 12
First usable sector is 40, last usable sector is 61079519
Partitions will be aligned on 8-sector boundaries
Total free space is 1 sectors (512 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              40        58720295   28.0 GiB    0700  APP
   2        58720296        58720615   160.0 KiB   0700  mts-mce
   3        58720616        58720935   160.0 KiB   0700  mts-mce_b
   4        58720936        58729127   4.0 MiB     0700  mts-proper
   5        58729128        58737319   4.0 MiB     0700  mts-proper_b
   6        58737320        58740071   1.3 MiB     0700  cpu-bootloader
   7        58740072        58742823   1.3 MiB     0700  cpu-bootloader_b
   8        58742824        58743847   512.0 KiB   0700  bootloader-dtb
   9        58743848        58744871   512.0 KiB   0700  bootloader-dtb_b
  10        58744872        58749991   2.5 MiB     0700  secure-os
  11        58749992        58755111   2.5 MiB     0700  secure-os_b
  12        58755112        58755239   64.0 KiB    0700  eks
  13        58755240        58755367   64.0 KiB    0700  eks_b
  14        58755368        58758439   1.5 MiB     0700  bpmp-fw
  15        58758440        58761511   1.5 MiB     0700  bpmp-fw_b
  16        58761512        58763559   1024.0 KiB  0700  bpmp-fw-dtb
  17        58763560        58765607   1024.0 KiB  0700  bpmp-fw-dtb_b
  18        58765608        58765927   160.0 KiB   0700  xusb-fw
  19        58765928        58766247   160.0 KiB   0700  xusb-fw_b
  20        58766248        58768295   1024.0 KiB  0700  rce-fw
  21        58768296        58770343   1024.0 KiB  0700  rce-fw_b
  22        58770344        58774439   2.0 MiB     0700  adsp-fw
  23        58774440        58778535   2.0 MiB     0700  adsp-fw_b
  24        58778536        58780583   1024.0 KiB  0700  sce-fw
  25        58780584        58782631   1024.0 KiB  0700  sce-fw_b
  26        58782632        58782887   128.0 KiB   0700  sc7
  27        58782888        58783143   128.0 KiB   0700  sc7_b
  28        58783144        59045287   128.0 MiB   0700  BMP
  29        59045288        59307431   128.0 MiB   0700  BMP_b
  30        59307432        59436455   63.0 MiB    0700  recovery
  31        59436456        59437479   512.0 KiB   0700  recovery-dtb
  32        59437480        59437607   64.0 KiB    0700  kernel-bootctrl
  33        59437608        59437735   64.0 KiB    0700  kernel-bootctrl_b
  34        59437736        59601575   80.0 MiB    0700  kernel
  35        59601576        59765415   80.0 MiB    0700  kernel_b
  36        59765416        59766439   512.0 KiB   0700  kernel-dtb
  37        59766440        59767463   512.0 KiB   0700  kernel-dtb_b
  38        59767464        59767471   4.0 KiB     0700  CPUBL-CFG
  39        59767472        59783855   8.0 MiB     0700  RP1
  40        59783856        59800239   8.0 MiB     0700  RP2
  41        59800240        60414639   300.0 MiB   0700  RECROOTFS
  42        60414640        61079518   324.6 MiB   0700  UDA

Another issue is that I can’t find the definition of APPSIZE, APPUUID, APPFILE in the sources under Linux_for_Tegra.
Where are they defined?

Linux_for_Tegra$ sudo grep -r APPSIZE
flash.sh:APP_TAG+="-e s/APPSIZE/${rootfssize}/ ";
Binary file bootloader/mkbctpart matches
bootloader/t186ref/cfg/flash_l4t_t194_spi_emmc_p3668.xml:            <size> APPSIZE </size>
bootloader/t186ref/cfg/flash_l4t_t194_spi_sd_p3668.xml:            <size> APPSIZE </size>
bootloader/t186ref/cfg/flash_t194_sdmmc.xml:            <size> APPSIZE </size>
bootloader/t186ref/cfg/flash_l4t_t186.xml:            <size> APPSIZE </size>

<partition name="APP" type="data">
    <allocation_policy> sequential </allocation_policy>
    <filesystem_type> basic </filesystem_type>
    <size> APPSIZE </size>
    <file_system_attribute> 0 </file_system_attribute>
    <allocation_attribute> 0x8 </allocation_attribute>
    <align_boundary> 4096 </align_boundary>
    <percent_reserved> 0 </percent_reserved>
    <unique_guid> APPUUID </unique_guid>
    <filename> APPFILE </filename>
    <description> **Required.** Contains the rootfs. This partition must be defined after
      `primary_gpt` so it can be accessed as the fixed known special device
      `/dev/mmcblk0p1`. </description>

hello MarukoBG,

you may have customize partition layouts to add another APP partition.
please also check flash.sh script file for those variable settings,