Jetson Orin board with A/B partition diagram showing unexpected slot switch to B
jetsonorinotabootnvbootctrlrootfs-abembedded linux

Jetson Orin rootfs-ab slot switches to B unexpectedly — nvbootctrl debug

Andres Campos ·

The rootfs-ab partition layout on Jetson Orin is the same mechanism OTA update systems use to switch between software versions — but it can also trigger unexpectedly when a device reboots without confirming successful boot. Understanding the retry counter is the key to preventing unintended slot switches in production.

Key Insights

  • The retry counter, not a filesystem check, controls slot switches — each unconfirmed reboot decrements a per-slot counter; when it hits 0, the bootloader marks the slot unbootable and tries the other
  • nvbootctrl mark-boot-successful must be called explicitly — the bootloader does not auto-confirm a successful boot; your software must call this
  • Watchdog resets and kernel panics look identical to the bootloader — the slot counter decrements regardless of why the device rebooted
  • nvbootctrl dump-slot-info is your primary diagnostic — shows retry counts, priority, and bootable status for both slots
  • Asymmetric retry counts signal the root cause — if slot A has retry_count=0 and slot B has retry_count=7, the device rebooted 7 times without calling mark-boot-successful

How Tegra rootfs-ab works

Jetson Orin uses a redundant partition layout when USE_REDUNDANT_FLASH_LAYOUT = "1" is set in the Yocto build. Each partition has two copies — A and B variants — including the rootfs.

The bootloader maintains a Boot Control Table (BCT) with per-slot metadata:

FieldDescription
priorityHigher priority slot boots first (default: A=15, B=14)
retry_countDecrements on each unconfirmed reboot; 0 = unbootable
successfulSet to 1 when mark-boot-successful is called

Boot sequence decision logic:

  1. Select the slot with highest priority where retry_count > 0
  2. Boot that slot and decrement its retry_count by 1
  3. If the OS calls mark-boot-successful → reset retry_count to 7, set successful = 1
  4. If the OS does NOT call mark-boot-successful (reboot/crash) → retry_count stays decremented
  5. When retry_count reaches 0 → mark slot unbootable, switch to the other slot

Diagnosing an unexpected switch

# Check current slot and retry counts
nvbootctrl dump-slot-info

# Example output:
# Current boot slot: 1
# Slot 0: priority=15, retry_count=0, successful=1, bootable=false
# Slot 1: priority=14, retry_count=5, successful=0, bootable=true

# One-line current slot check
nvbootctrl get-current-slot
# Output: 1

# Check if current slot was marked successful
nvbootctrl is-slot-marked-successful $(nvbootctrl get-current-slot)
# Output: 0 (not yet marked successful)

When retry_count=0 and successful=1 on slot A, slot A was successfully marked at least once but then had its retry counter re-decremented — meaning the device rebooted after a mark-boot-successful call but the OS didn’t call it again after that reboot.

Fixing the retry counter

# Reset slot A to healthy state (run from the device)
nvbootctrl set-active-boot-slot 0      # make A the active slot
nvbootctrl mark-boot-successful        # mark current boot as successful

# Verify
nvbootctrl dump-slot-info
# Slot 0: priority=15, retry_count=7, successful=1, bootable=true

If retry_count cannot be restored via mark-boot-successful (slot 0 is marked unbootable), you need to flash slot A via SDK Manager or flash.sh.

Calling mark-boot-successful reliably

The correct place is a systemd service that runs after your application confirms it is healthy:

# /etc/systemd/system/boot-confirm.service
[Unit]
Description=Mark boot slot as successful
After=multi-user.target
Requires=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/nvbootctrl mark-boot-successful

[Install]
WantedBy=multi-user.target

Enable it:

systemctl enable boot-confirm.service

For applications that take time to start, add a health check before confirming:

#!/bin/bash
# /usr/local/bin/confirm-boot.sh
# Wait for application to become healthy, then confirm boot

until curl -sf http://localhost:8080/health; do
    sleep 2
done

nvbootctrl mark-boot-successful
logger "Boot slot $(nvbootctrl get-current-slot) confirmed successful"

Common causes of unexpected switches

Root causeSymptomFix
mark-boot-successful never calledretry_count decrements on every rebootAdd boot-confirm.service
Watchdog reset during startupretry_count decrements before app is readyCall mark-boot-successful after health check
Kernel panicDevice reboots without confirmingFix kernel panic; check dmesg after switch
Power loss during bootretry_count decrements, may corrupt in-progress OTAEnsure stable power; add voltage monitoring
OTA update stale stateOTA set slot B active but never confirmedOTA client must call mark-boot-successful after successful update

Recovering a fully unbootable device

If both slots reach retry_count=0, the device will not boot. Recovery requires flashing via recovery mode:

# Put device in recovery mode (hold FORCE_RECOVERY button, power cycle)
# On host:
sudo ./flash.sh jetson-agx-orin-devkit mmcblk0p1

For A/B-aware flashing that only updates slot A without touching slot B:

sudo ./flash.sh --no-flash jetson-agx-orin-devkit mmcblk0p1
# Then flash specific partitions via tegraflash

For the OTA update workflow that uses this mechanism, see Jetson A/B OTA updates on custom carrier boards. For flashing procedures and partition layout options, see flash.sh on Jetson Orin — complete guide.

FAQ

Why does my Jetson Orin keep booting from the B partition instead of A?

The slot A retry counter reached 0 after repeated reboots without nvbootctrl mark-boot-successful. Every reboot — including watchdog resets and kernel panics — decrements the counter. Once it hits 0, the bootloader marks slot A unbootable and switches to slot B.

How do I check which slot Jetson Orin is currently booting from?

Run nvbootctrl dump-slot-info to see retry counts and bootable status for both slots, or nvbootctrl get-current-slot for a one-line answer.

How do I prevent the Jetson from switching slots after a planned reboot?

Call nvbootctrl mark-boot-successful once your application has confirmed it is healthy. A systemd oneshot service that runs after multi-user.target is the standard approach.

Can I manually force Jetson to boot from a specific slot?

Yes. Run nvbootctrl set-active-boot-slot 0 for slot A or nvbootctrl set-active-boot-slot 1 for slot B. The change takes effect on the next reboot.


NVIDIA Jetson Expert Support

Stuck on a Jetson bring-up?

We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA, most blockers clear in the first session. No long retainers. No guessing.

Frequently Asked Questions

Why does my Jetson Orin keep booting from the B partition instead of A?

When a slot's retry counter reaches 0, the bootloader marks it unbootable and switches to the other slot. This happens when the device reboots (watchdog reset, kernel panic, power loss) before nvbootctrl mark-boot-successful is called, decrementing the retry count each time. After 7 failed attempts, the bootloader switches slots.

How do I check which slot Jetson Orin is currently booting from?

Run nvbootctrl dump-slot-info from the running system. It shows the current slot, retry count, and whether each slot is marked bootable. Also check nvbootctrl get-current-slot for a one-line answer.

How do I prevent the Jetson from switching slots after a planned reboot?

Call nvbootctrl mark-boot-successful once your application has started successfully. Put this in a systemd service that runs after your application is confirmed healthy. Without this call, every reboot decrements the retry counter toward zero.

Can I manually force Jetson to boot from a specific slot?

Yes. Run nvbootctrl set-active-boot-slot 0 to set slot A, or nvbootctrl set-active-boot-slot 1 to set slot B. The change takes effect on the next reboot. This is the same command used by OTA update systems to activate a newly flashed slot.

Andrés Campos, Co-Founder & CTO at ProventusNova

Written by

Andrés Campos

Co-Founder & CTO · ProventusNova

8 years deep in embedded systems, from underwater ROVs to edge AI. Andrés leads every technical delivery personally.

Connect on LinkedIn