Jetson TX2NX SecureBoot OTA update doesn't switch partitions

Hello! I’m trying to find a way to update Kernel & DeviceTree remotely on a SecureBoot’ed & eMMC encrypted TX2NX device, without updating Linux for Tegra version (R32.7.5)

I have tried replacing partitions but it’s not working, as per my post previously: Updating Kernel & DTB via dd command on TX2NX with SecureBoot

Now I am trying to use OTA package as instructed by the Nvidia employee in my previous post. The issue is that whenever I start OTA update with nv_ota_start.sh, it ends with Bootloader on non-current slot(B) is updated line.

This is the way I’m building payload package & running the OTA update.

PC with Ubuntu 18.04 and Nvidia SDK installed:

  1. Download & unzip ota_tools_r32.7.5_aarch64.tbz2 in Linux_for_Tegra directory
  2. Download & unzip secureboot_r32.7.5_aarch64.tbz2 in Linux_for_Tegra directory
  3. Build base recovery image:
    Note: I’m calling R32-6 as the version because R32-7 is not working at all. It says that my system image is R32-6, even though it is not - when I use R32-6 it works without an error.
cd Linux_for_Tegra
sudo ./tools/ota_tools/version_upgrade/build_base_recovery_image.sh --user_key {USER_KEY_PATH} -u {RSA_PKC_KEY_PATH} jetson-xavier-nx-devkit-tx2-nx R32-6 /mnt/flashing/DevFlasher/Linux_for_Tegra /mnt/flashing/DevFlasher/Linux_for_Tegra/rootfs /mnt/flashing/DevFlasher/Linux_for_Tegra

Now I’m wondering if it’s fine to build image if the destination L4T and Target L4T folders are the same? I don’t want to upgrade anything except for the Kernel and DeviceTree.

  1. Create OTA payload package (with -b flag as bootloader only, I don’t need to replace rootfs):
cd Linux_for_Tegra
sudo ./tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh -b --user_key {USER_KEY_PATH} -u {RSA_PKC_KEY_PATH} -v {SKB_KEY_PATH} jetson-xavier-nx-devkit-tx2-nx R32-6

Jetson TX2NX:
6. Copy ota_payload_package.tar.gz to Jetson TX2NX device:

cd Linux_for_Tegra
./bootloader/jetson-xavier-nx-devkit-tx2-nx/ota_payload_package.tar.gz jetson@192.168.55.1:/home/jetson/
  1. Download & unzip ota_tools_r32.7.5_aarch64.tbz2 on Jetson TX2NX device & start update
tar -xf ota_tools_r32.7.5_aarch64.tbz2
cd Linux_for_Tegra/tools/ota_tools/version_upgrade/
sudo ./nv_ota_start.sh /dev/mmcblk0 /home/jetson/air_update/ota_payload_package.tar.gz

This is the output of nv_ota_start.sh when running the first time:

OTA_LOG_FILE=/ota_log/ota_20241219-160936.log
Extract /home/jetson/air_update/ota_payload_package.tar.gz
update_nv_boot_control_in_rootfs /ota_work
3636--0001--1--jetson-xavier-nx-devkit-tx2-nx-
check_prerequisites
get_chip_id chip_id
Skip checking root device for non-T194 devices
decompress_ota_package ota_package.tar /ota_work
decompress_ota_package: start at C  dec 19 16:09:38 UTC 2024
Sha1 checksum for /ota_work/ota_package.tar (8ae778b057183ea4c1d127b24391afa95bed5026) matches
decompress_ota_package: end at C  dec 19 16:09:39 UTC 2024
nv_ota_update_without_layout_change.sh
Command: nv_ota_update_without_layout_change.sh
check_target_board /ota_work TARGET_BOARD
get_chip_id CHIP_ID
update_utilities_for_BUP_update /ota_work
enable_a_b_redundancy
get_rootfs_a_b_enabled ROOTFS_AB_ENABLED UNIFIED_AB_ENABLED
ROOTFS_AB_ENABLED=0
UNIFIED_AB_ENABLED=0
check_bsp_version /ota_work BASE_VERSION
get_update_control /ota_work UPDATE_BOOTLOADER UPDATE_ROOTFS
UPDATE_BOOTLOADER=1, UPDATE_ROOTFS=0
update_bootloader /ota_work 0 0x18
get_update_slot bootloader 0 update_slot
update_slot=B
update_bootloader_with_UE /ota_work 0x18
Nvidia A/B-Redundancy Update tool Version 2.1
verifying update
Verify bootloader update begins.
The rotate count has been restored.
The current slot 0 is marked as boot successful
Invalid state is detected: non-current slot is bootable but didn't boot successfully.
Verify rootfs update begins.
RootFS A/B is not enabled, verification finishes.
Nvidia A/B-Redundancy Update tool Version 2.1
Got payload file: /ota_work/bl_update_payload
current slot 0
SM: S11
Set slot 1 as unbootable and start updating.
Start running: /usr/sbin/nv_bootloader_payload_updater --no-dependent-partition /ota_work/bl_update_payload
Got update payload: /ota_work/bl_update_payload
Tegra User Block Device: /dev/disk/by-partlabel
Tegra Boot Block Device: /dev/mmcblk0boot0
HEADER: MAGIC NVIDIA__BLOB__V2
HEX_VALUE 16909857
BLOB_SIZE 5274838
HEADER_SIZE 48
NUMBER_OF_ELEMENTS 18
HEADER_TYPE 0
UNCOMP_SIZE 5274838
MB1_RATCHET_LV 0
MTS_RATCHET_LV 0
ROLLBACK_FUSE_LV 0
Device TN Spec: 3636-301-0001-D.0-1-0-jetson-xavier-nx-devkit-tx2-nx-internal
Device Compatible Spec: 3636--0001--1--jetson-xavier-nx-devkit-tx2-nx-
Device TN Spec: 3636-301-0001-D.0-1-0-jetson-xavier-nx-devkit-tx2-nx-internal
Device Compatible Spec: 3636--0001--1--jetson-xavier-nx-devkit-tx2-nx-
Device is fused board.
ENTRY_TABLE:
PART  POS  LEN  VER TNSPEC TYPE UPDATABLE
bpmp-fw  2208  534816  12914    1  1
sce-fw  537024  126032  12914    1  1
cpu-bootloader  663056  309552  12914    1  1
mb2  972608  122784  12914    0  1
spe-fw  1095392  95984  12914    0  1
adsp-fw  1191376  77616  12914    1  1
secure-os  1268992  403264  12914    1  1
mb1  1672256  99904  12914    2  1
mts-bootpack  1772160  2236640  12914    1  1
mts-preboot  4008800  58384  12914    0  1
sc7  4067184  23632  12914    1  1
bpmp-fw-dtb  4090816  113648  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  1  1
bootloader-dtb  4204464  194096  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  1  1
VER  4398560  102  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  0  1
BCT  4398662  3584  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  2  1
MB1_BCT  4402246  49360  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  0  1
kernel  4451606  629136  12914    1  1
kernel-dtb  5080742  194096  12914  3636-300-0001--1-0-jetson-xavier-nx-devkit-tx2-nx-mmcblk0p1  1  1
Saving Entry table to /opt/ota_package/entry_table
Writing 534816 bytes to /dev/disk/by-partlabel/bpmp-fw_b for bpmp-fw
Writing 126032 bytes to /dev/disk/by-partlabel/sce-fw_b for sce-fw
Writing 309552 bytes to /dev/disk/by-partlabel/cpu-bootloader_b for cpu-bootloader
mb2 write: slot = 1 offset = 1276928 bytes = 122784
spe-fw write: slot = 1 offset = 883712 bytes = 95984
Writing 77616 bytes to /dev/disk/by-partlabel/adsp-fw_b for adsp-fw
Writing 403264 bytes to /dev/disk/by-partlabel/secure-os_b for secure-os
Writing 2236640 bytes to /dev/disk/by-partlabel/mts-bootpack_b for mts-bootpack
mts-preboot write: slot = 1 offset = 1801216 bytes = 58384
Writing 23632 bytes to /dev/disk/by-partlabel/sc7_b for sc7
Writing 113648 bytes to /dev/disk/by-partlabel/bpmp-fw-dtb_b for bpmp-fw-dtb
Writing 194096 bytes to /dev/disk/by-partlabel/bootloader-dtb_b for bootloader-dtb
VER write: slot = 1 offset = 4063232 bytes = 102
MB1_BCT write: slot = 1 offset = 622592 bytes = 49360
Writing 629136 bytes to /dev/disk/by-partlabel/kernel_b for kernel
Writing 194096 bytes to /dev/disk/by-partlabel/kernel-dtb_b for kernel-dtb
Update bup successfully
SM: S12
Setting slot 1 as active boot slot
Copy /opt/ota_package/entry_table into /ota_work/entry_table.ota_backup
Bootloader on non-current slot(B) is updated

This is when running second, third time, etc.

### OTA log ###
OTA_LOG_FILE=/ota_log/ota_20241219-132028.log
update_nv_boot_control_in_rootfs /ota_work
check_prerequisites
get_chip_id chip_id
Skip checking root device for non-T194 devices
decompress_ota_package ota_package.tar /ota_work
decompress_ota_package: start at C  dec 19 13:20:30 UTC 2024
Sha1 checksum for /ota_work/ota_package.tar (b2a0302cf88abd31c2eda26aa79d3e40905a7e5d) matches
decompress_ota_package: end at C  dec 19 13:20:30 UTC 2024
nv_ota_update_without_layout_change.sh
Command: nv_ota_update_without_layout_change.sh
check_target_board /ota_work TARGET_BOARD
get_chip_id CHIP_ID
update_utilities_for_BUP_update /ota_work
enable_a_b_redundancy
get_rootfs_a_b_enabled ROOTFS_AB_ENABLED UNIFIED_AB_ENABLED
ROOTFS_AB_ENABLED=0
UNIFIED_AB_ENABLED=0
check_bsp_version /ota_work BASE_VERSION
get_update_control /ota_work UPDATE_BOOTLOADER UPDATE_ROOTFS
UPDATE_BOOTLOADER=1, UPDATE_ROOTFS=0
update_bootloader /ota_work 0 0x18
get_update_slot bootloader 0 update_slot
update_slot=B
update_bootloader_with_UE /ota_work 0x18
Remove exsting /opt/ota_package/entry_table
Copy /opt/ota_package/entry_table into /ota_work/entry_table.ota_backup
Bootloader on non-current slot(B) is updated

Why is it updating to a non-current slot? Where can I select the slot to update? I want to use A slot.
When trying to set bootloader with sudo nvbootctrl set-active-boot-slot 1 and rebooting, nothing changes.

This is the output of sudo nvbootctrl dump-slots-info post-reboot:

Current bootloader slot: A
Active bootloader slot: B
magic:{DELETED FOR FORUMS},             version: 5             features: 3             num_slots: 2
slot: 0,             priority: 14,             suffix: _a,             retry_count: 7,             boot_successful: 1
slot: 1,             priority: 15,             suffix: _b,             retry_count: 7,             boot_successful: 1

hello therealmatiss,

I’ve tested OTA payload to update bootloader remotely on rel-35 only.
may I have more details of your use-case, besides, please refer to an Image-Based OTA Update.

The use case is simple - updating kernel remotely & automatically on a SecureBoot’ed device. Previously I have been using sudo dd to replace Kernel & DTB partitions without SecureBoot. With SecureBoot enabled though, the sudo dd way is not working - it just doesn’t boot after that (Updating Kernel & DTB via dd command on TX2NX with SecureBoot)

I did refer to the documentation - those are exactly the same steps I took as I have mentioned here in my post, except that I’m skipping system image update - only the bootloader part, which contains Kernel & DTS.

could you please see-also Updating an Individual Partition.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.