jetsonotaa/b slotbspjetpack 6carrier board

Jetson A/B OTA updates: what breaks on custom carrier boards

Andres Campos ·

Key Insights

  • Jetson Orin A/B OTA works on devkits but breaks on custom carrier boards in four specific ways
  • Slot switching that doesn’t persist: usually QSPI write protection or ODMDATA mismatch between slots
  • Unexpected slot B switches: the retry counter on slot A incremented too many times — investigate the underlying reboots, not the slot switch itself
  • Rollback protection in L4T R36.4+ blocks downgrading — JP5 → JP6 OTA is not possible; reflash only
  • Verify slot B is initialized before shipping: nvbootctrl dump-slots-info should show both slots bootable after initial flash

How Jetson Orin A/B slots work

Jetson Orin uses a redundant boot partition scheme inspired by Android A/B updates. Each slot (A and B) contains a complete, independent set of bootloader partitions:

  • kernel_a / kernel_b — Linux kernel images
  • kernel-dtb_a / kernel-dtb_b — Device tree blobs
  • system_a / system_b (if using A/B rootfs)
  • Bootloader partitions in QSPI: mb2, xusb-fw, bpmp-fw, etc.

During a normal OTA update:

  1. Update engine writes the new firmware to the inactive slot
  2. Verifies the write
  3. Sets the inactive slot as the new active slot
  4. Reboots
  5. UEFI boots from the new slot and marks it as successful

If the new slot fails to boot (watchdog timeout, kernel panic, boot count exceeded), UEFI reverts to the previous slot automatically. This is the rollback mechanism.

On devkits, this works. On custom carrier boards, multiple things can go wrong.

Failure mode 1: slot switching doesn’t persist across reboot

The most common forum complaint: “OTA appears to complete, reboot happens, but the system comes back on the old slot.”

This means the slot switch command was accepted by UEFI but not committed to persistent storage (QSPI) before reboot. Causes:

QSPI write protection active. If your carrier board has QSPI write protection enabled (hardware WP signal or software protection), UEFI can read the boot order but can’t update it. The switch appears to work in RAM but reverts on power cycle.

Check: during the OTA process, look for UEFI log messages about QSPI write failures. Also check your carrier board’s QSPI WP pin — it should be deasserted (write enabled) during normal operation.

Wrong ODMDATA for the switching slot. If slot B has different ODMDATA than slot A (because slot B was initialized from a different flash configuration), UEFI may read the ODMDATA and determine the new slot is invalid for this carrier board. It silently reverts to slot A.

Fix: ensure both slots are flashed with the same carrier board configuration. When running the initial flash of a custom carrier board, flash with a full dual-slot write — not just slot A.

# Verify current slot ODMDATA from running system
cat /proc/device-tree/chosen/nvidia,odmdata | xxd

# Check what's in QSPI for both slots
sudo nvbootctrl dump-slots-info

Failure mode 2: rollback protection blocking updates

L4T R36.4 and R36.5 (JetPack 6.2.x) tightened rollback protection significantly. The firmware now checks a monotonic counter in QSPI that increments with each OTA. Once a firmware version is burned in, older versions are rejected.

Symptoms:

  • OTA update is downloaded and verified
  • update_engine reports success
  • Reboot happens but system stays on old firmware
  • dmesg shows UEFI rollback rejection

This creates problems when:

  • A field device gets an OTA update and you need to roll back due to a bug
  • You’re testing OTA from a higher version back to a lower version in the lab
  • JP5 → JP6 OTA is attempted (not supported at all — the version gap triggers rollback protection)

The rollback protection is intentional and cannot be disabled without disabling secure boot. The practical implication: you can only push OTA updates forward (to higher version numbers), and JP5 → JP6 requires a full reflash, not OTA.

# Check current slot versions and anti-rollback state
sudo nvbootctrl dump-slots-info

If you need to test downgrade in a lab environment, you need to reflash with the full bootchain from recovery mode.

Failure mode 3: slot B not initialized on custom carrier boards

On devkits, NVIDIA’s flash.sh script initializes both slots. Some custom carrier board vendors provide modified flash tools or reduced flash scripts that only write slot A. Slot B is left with whatever was in QSPI from the factory — often a previous test firmware or an empty partition.

When OTA writes to slot B and tries to boot from it:

  • UEFI reads slot B’s ODMDATA — wrong or corrupted
  • UEFI marks slot B as unbootable and reverts to slot A
  • OTA appears to fail silently

Check if slot B is properly initialized:

# On a running Jetson
sudo nvbootctrl dump-slots-info

# Output shows something like:
# Current Boot Slot: 0 (a)
# Active Slot: 0 (a)  
# Slot 0:   Bootable: yes, Priority: 14, Retry Count: 7
# Slot 1:   Bootable: no, Priority: 0, Retry Count: 0

If slot B shows Bootable: no and Priority: 0 before any OTA has been run, it was never initialized. Initialize it by running a full flash that includes the --no-external-device flag and explicitly writes both slots, or by using nvbootctrl to initialize the slot metadata and then running OTA.

Failure mode 4: unexpected slot B switches under load

The forum thread with 89 replies on “Orinnx reboot repeatedly but it switch to B unexpectly” is this failure mode: the system is running normally, something causes a crash or unexpected reboot, and the retry counter on slot A increments. After a configurable number of failed boots (default is typically 7), UEFI marks slot A as unbootable and switches to B.

If slot B has older firmware, the system appears to have “downgraded” spontaneously.

The real question is: what’s causing the repeated reboots in the first place? The slot switching is the symptom, not the root cause. Common underlying causes:

  • Kernel panic or watchdog timeout (check /var/log/kern.log or journalctl -k)
  • Power rail instability causing unexpected resets (SYS_RESET* assertion)
  • Thermal throttle leading to CPU stall

Diagnostic steps:

# Check last reboot reason
sudo cat /proc/last_reset_reason 2>/dev/null

# Check kernel crash dumps if kdump is configured
ls /var/crash/

# Check boot retry counts
sudo nvbootctrl dump-slots-info | grep "Retry Count"

Manually reset the retry counter to prevent premature slot switching during debugging:

# Reset slot A retry count (use with caution)
sudo nvbootctrl set-slot-as-unbootable 1    # Mark B as unbootable temporarily
sudo nvbootctrl set-active-boot-slot 0       # Force back to slot A
sudo nvbootctrl set-slot-as-bootable 1       # Re-enable B when ready

What to do during initial flash for custom carrier boards

Set both slots up correctly from the start. When you run your first flash:

  1. Use flash.sh with your carrier board config, not a reduced script
  2. Verify both slots after flash: nvbootctrl dump-slots-info should show both slots bootable
  3. Boot from slot A, verify everything works
  4. Boot from slot B manually (nvbootctrl set-active-boot-slot 1 && reboot) and verify slot B boots correctly

Discovering slot B is broken during an OTA in production is much worse than catching it during bring-up.

For related carrier board bring-up issues, see Jetson carrier board not booting: 6 root causes and our UEFI shell assertion post — a corrupted OTA often lands you there. If you’re dealing with a JetPack version mismatch between slots, see upgrading from JetPack 5 to JetPack 6 for the full scope of what changed. If you’re debugging OTA failures in production hardware, book a scoping call.

NVIDIA’s OTA update documentation for Jetson Linux is in the Over-the-Air Update section of the developer guide. The nvbootctrl tool reference is in the same guide under Bootloader Control Block.

Frequently Asked Questions

Why does Jetson Orin switch to slot B unexpectedly after a reboot?

Slot A has been marked unbootable — either because an OTA write failed verification, because the boot retry counter exceeded the rollback threshold, or because UEFI couldn’t find a valid kernel in slot A. Check with sudo nvbootctrl dump-slots-info.

How do I check which A/B slot Jetson is booting from?

Run sudo nvbootctrl dump-slots-info. Also check /proc/cmdline for androidboot.slot_suffix=_a or _b.

What is rollback protection on Jetson and how does it affect OTA?

Rollback protection prevents downgrading firmware to an earlier version. L4T R36 (JetPack 6) tightened this in R36.4 and R36.5. OTA updates must always move to a higher version number. JP5 → JP6 via OTA is not supported.

Does slot B need to be flashed separately during initial board setup?

On devkits, flash.sh handles both slots. On custom carrier boards with vendor flash tools, slot B may not be initialized. An uninitialized slot B causes OTA failures when the update tries to use it.

Can I recover a Jetson stuck in a bad OTA state without reflashing?

Sometimes. If the active slot still boots, use sudo nvbootctrl set-active-boot-slot 0 (or 1) to force back to the known-good slot and reboot. If both slots are corrupted, reflash via recovery mode is required.


ProventusNova handles Jetson OTA infrastructure for production deployments on custom carrier boards. If A/B update failures are blocking your product, book a scoping call.