How to restore a raw backup (split images) to a Fused (Secure Boot + fTPM) Orin NX?

Hi everyone,

I am working with a Jetson Orin NX 16GB module. I have successfully migrated to L4T 36.4.3 (JetPack 6).

Current Status:

  • I have burned the fuses (PKC + SBK).

  • I have enabled fTPM (compiled OP-TEE with -t flag).

  • I verified that the device is secured: dmesg | grep -i "Secure boot" shows enabled.

My Problem: Before burning the fuses and enabling encryption, I had taken a backup of my working system. This backup consists of split raw image chunks (created via the backup tools), looking like this: image1.img, image2.imgimage16.img, along with an info file.

My Questions:

  1. Since the target is now fused (Secure Boot Active), I understand I cannot simply flash the old bootloader components. I need to re-sign the bootloader while restoring my old RootFS.

  2. What is the correct procedure to combine these split images into a single system.img? (Is cat image*.img > system.imgsufficient, or do I need to be careful about sorting?)

  3. What is the exact l4t_initrd_flash.sh command to flash this restored system.img to the fused target using my keys (rsa_priv.pem and sbk.key)?

I want to make sure I use the -r (reuse image) flag correctly without bricking the secured device.

Environment:

  • Module: Jetson Orin NX 16GB

  • Carrier: Custom (using jetson-orin-nano-devkit-super config)

  • Release: R36.4.3

Thanks in advance for your help.

*** Please note that this reply is generated by LLM automatically ***

To address your question, I’ll break down the steps to combine the split images, resign the bootloader, and flash the restored image to the fused Jetson Orin NX target.

Combining split images:

You have a backup of your working system consisting of split raw image chunks created via the backup tools. To combine these images, you can use the tegraflash.py tool, which is part of the NVIDIA Jetson SDK.

The tegraflash.py tool has an option to combine split images using the --combine flag. The general syntax is:

tegraflash.py --combine <image1> <image2> ... <imageN> --output <output_image>

Replace <image1>, <image2>, …, <imageN> with the names of your split image chunks, and <output_image> with the desired name of the combined image.

For example:

tegraflash.py --combine boot.img.1 boot.img.2 boot.img.3 --output boot.img

This will combine the three split image chunks into a single image file named boot.img.

Resigning the bootloader:

Since you have enabled Secure Boot and burned the fuses, you need to resign the bootloader with your custom keys. You can use the tegraflash.py tool with the --sign flag to resign the bootloader.

The general syntax is:

tegraflash.py --sign <bootloader_image> --key <private_key> --cert <certificate>

Replace <bootloader_image> with the name of your bootloader image, <private_key> with the path to your private key file, and <certificate> with the path to your certificate file.

For example:

tegraflash.py --sign bootloader.bin --key my_private_key.pem --cert my_certificate.pem

This will resign the bootloader image with your custom keys.

Flashing the restored image:

To flash the restored image to the fused target, you can use the tegraflash.py tool with the --flash flag. The general syntax is:

tegraflash.py --flash <image> --reuse-image --secure-dev

Replace <image> with the name of your combined and resigned image file.

The --reuse-image flag is used to reuse the existing image on the device, and the --secure-dev flag is used to indicate that the device is in secure mode.

For example:

tegraflash.py --flash boot.img --reuse-image --secure-dev

This will flash the restored image to the fused target using your custom keys.

Additional notes:

  • Make sure to use the correct configuration file (R3643 in your case) when flashing the image.
  • Be careful when using the --reuse-image flag, as it can potentially brick the device if not used correctly.
  • Make sure to verify the integrity of the image before flashing it to the device.

By following these steps, you should be able to combine the split images, resign the bootloader, and flash the restored image to the fused Jetson Orin NX target using your custom keys.

*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***

hello OswaldUK,

may I have the actual use-case to backup a fused target’s image?

besides.. it’s backup/restore script limitation with ROOTFS_ENC devices.
it must to run flash script for users to deploy devices with disk encryption for using a generic key.
here’re brief steps
a) add --massflash option to generate a massflash package,
$ sudo BOARDID=3767 BOARDSKU=0000 ./tools/kernel_flash/l4t_initrd_flash.sh --network usb0 -p "-c bootloader/t186ref/cfg/flash_t234_qspi.xml" --no-flash jetson-orin-nano-devkit internal
$ sudo BOARDID=3767 BOARDSKU=0000 ROOTFS_ENC=1 ./tools/kernel_flash/l4t_initrd_flash.sh --network usb0 --showlogs --no-flash --external-device nvme0n1p1 -S 16GiB -c ./tools/kernel_flash/flash_l4t_t234_nvme_rootfs_enc.xml --external-only --append -i ./disk_enc.key ``-p "--generic-passphrase"`` --massflash 2 jetson-orin-nano-devkit external
b) it’s a massflash (mfi_.tar.gz) package, by extracting this package, you should then putting two Orin Nano DevKits into recovery mode, and flashing them simultaneously to enable disk encryption.
$ sudo tar xpfv mfi_<target-board>.tar.gz.
$ cd mfi_<target-board>
$ sudo ./tools/kernel_flash/l4t_initrd_flash.sh --flash-only --massflash 2

Hello Jerry,

Thank you for the massflash suggestion. However, my use case is currently focused on restoring a specific Image backup to a single unit that has already been fused, rather than mass production deployment yet.

To clarify my situation:

  1. Current State: I have an Orin NX 16GB running L4T 36.4.3.

  2. Security: The device is fused (PKC + SBK) and fTPM is enabled (OP-TEE compiled with -t, following the RidgeRun guide: RidgeRun Platform Security Manual - NVIDIA Jetson).

  3. Verification: The device currently boots successfully with the stock NVIDIA rootfs, and dmesg | grep "Secure boot"confirms it is enabled.

The Backup Source: I have a backup of my custom rootfs taken before the fusing process. This backup was created using a custom script that utilizes Partclone, not dd. Here is the relevant snippet of the backup script used for the APP partition:

…

clonePartition() {
# …
# Creating image1.img for APP partition
partclone.ext4 -c -d -s $cloningPartDev -o $outputFile.img
# …
}

…

My Proposed Restoration Workflow: Since image1.img is in a proprietary Partclone format (not a raw image), I cannot simply use it directly. I plan to perform the following steps. Could you please confirm if this is the valid and safe approach for a fused target?

Step 1: Convert Backup to Raw Image I will restore the partclone image to a raw ext4 file on my host machine: cat image1.img | partclone.ext4 -r --restore_raw_file -o system.img

Step 2: Flash with Reuse Image (-r) I will place this restored system.img into Linux_for_Tegra/bootloader/ and use the flash script to re-sign the bootloader components (using my keys) while keeping my custom rootfs data.

My command:

sudo ./tools/kernel_flash/l4t_initrd_flash.sh
-u ./key_store/rsa_priv.pem
-v ./key_store/sbk.key
–external-device nvme0n1p1
-c tools/kernel_flash/flash_l4t_t234_nvme.xml
-r
–network usb0
jetson-orin-nano-devkit-super internal

Questions:

  1. Is this workflow correct for restoring a custom rootfs to a device that has fTPM enabled and Fuses burned?

  2. Does the -r flag combined with -u/-v correctly handle the signing of the bootloader components while injecting the provided system.img?

Thank you for your support.

I’m experiencing the similar issue, could you help me? @WayneWWW @DaneLLL @JerryChang @KevinFFF

hello OswaldUK,

let me have confirmation of your base/target device authorization status.
for instance,
are you going to backup the root file system image from Orin-NX-A (fused with key chain-A),
and then restore that image onto Orin-NX-B (fused with key chain-B)?

Hi,

Let me clarify the exact scenario to avoid confusion regarding keys:

  1. Source Device (Dev Unit): The backup was taken from a different Orin NX unit that was Unfused and Unencrypted (Development state).

    • Therefore, the source image is RAW (Plain ext4). It is NOT encrypted with any device-specific key.
  2. Target Device (Production Unit): The target is a new Orin NX unit that is Fused (PKC+SBK) with fTPM enabled

hello OswaldUK,

you may see-also.. $OUTLinux_for_Tegra/nv_tools/scripts/nv_customize_rootfs.sh

Thanks for the pointer regarding nv_customize_rootfs.sh.

I understand that the rootfs needs to be compatible with the target. Instead of relying on the script, I am manually performing the necessary clean-up on the raw system.img (by loop mounting it) to ensure it boots correctly. Specifically, I am editing /etc/fstab to comment out the old UUID references for Swap, Log, and Data partitions that do not exist in the standard partition layout yet.

I need a clear confirmation on the flashing mechanism itself to avoid bricking the fused hardware.

My proposed workflow is:

  1. Prepare Image: I place my custom, raw (unencrypted/signed) system.img (with cleaned fstab) into Linux_for_Tegra/bootloader/.

  2. Flash Command: I run the initrd flash script with the Reuse Image (-r) flag along with my fuse keys:

    sudo ./tools/kernel_flash/l4t_initrd_flash.sh 
    -u ./key_store/rsa_priv.pem 
    -v ./key_store/sbk.key 
    –external-device nvme0n1p1 
    -c tools/kernel_flash/flash_l4t_t234_nvme.xml 
    -r 
    jetson-orin-nano-devkit-super internal
    
    
    

When using -r (reuse image) combined with -u / -v (keys) on a Fused device: Does the script automatically generate and SIGN the necessary bootloader components (MB1, MB2, UEFI, etc.) from scratch using the provided keys, while simply injecting my custom system.img as the APP partition?

I want to confirm that the -r flag does NOT attempt to reuse old/unsigned bootloader artifacts, which would cause a BootROM rejection.

Thanks.

hello OswaldUK,

you may proceed to the flashing process as long as you’re using the identical PKC/SBK keys.
it’s fuse-based bootloader secure boot so that the root-of-trust can start from the BootROM, you’ll see the errors reports as below and abort the process if you did not given keys to the fused target.
for instance,
Error: Either RSA key file is not provided or SBK key file is provided for PKC protected target board.

yes, it’s -r options to skip building system.img ; reuse the existing one for flashing.
however, bootloader components will being sign/encrypt according to your key files.

Thank you for the confirmation,

I am trying to flash a custom system.img (restored from a backup) to a Fused Orin NX 16GB module (running R36.4.3) using l4t_initrd_flash.sh with the --reuse flag.

I have replaced the stock Linux_for_Tegra/bootloader/system.img with my custom raw image.

Even though I am providing the specific BOARDID, FAB, and BOARDSKU variables for the Orin NX, the script fails by attempting to use the SD Card partition table configuration (flash_t234_qspi_sd.xml), which causes an error because the target is an Orin NX module (NVMe only, no SD card).

Here is the command I used:

sudo BOARDID=“$BOARD_ID” FAB=“$FAB” BOARDSKU=“$BOARDSKU” CHIP_SKU=“$CHIP_SKU” RAMCODE_ID=“$RAMCODE”
./tools/kernel_flash/l4t_initrd_flash.sh
-u ./R36.4.3/Linux_for_Tegra/l4t/tools/flashtools/flash/rsa_priv.pem
-v ./R36.4.3/Linux_for_Tegra/l4t/tools/flashtools/flash/sbk.key
–external-device nvme0n1p1
-c tools/kernel_flash/flash_l4t_t234_nvme.xml
–reuse
–showlogs
–network usb0
jetson-orin-nano-devkit-super internal

And here is the error log:

Error: Using a flash partition table config file of SD card, /opt/x8-orin-installer/orin_36-4-3_EPU2-0/R36.4.3/Linux_for_Tegra/bootloader/generic/cfg/flash_t234_qspi_sd.xml, but the target board does not have SD card
To bypass this error, please add your board information to the board_with_sdcard array in this script.
Error: failed to generate images
Cleaning up…

It seems the script defaults to the SD card QSPI config when jetson-orin-nano-devkit-super is used, ignoring the fact that it is an Orin NX.

How can I force the script to use the correct QSPI configuration for NVMe (Orin NX) while using the --reuse flag? Do I need to explicitly pass the QSPI config using -p?

Thanks.

hello OswaldUK,

it’s -c option to assign the xml file for internal storage, you may also try below to flash only QSPI.
for instance,
$ sudo ./tools/kernel_flash/l4t_initrd_flash.sh -u PKC.pem -v SBK.key -p "-c bootloader/generic/cfg/flash_t234_qspi.xml --no-systemimg" jetson-orin-nano-devkit internal

Hello Jerry,

the flashing process stops at Step 2 with the following error:

****************************************************
* *
* Step 2: Boot the device with flash initrd image *
* *
****************************************************
/opt/x8-orin-installer/orin_36-4-3_EPU2-0/R36.4.3/Linux_for_Tegra/tools/kernel_flash/l4t_initrd_flash_internal.sh: line 628: pushd: /opt/x8-orin-installer/orin_36-4-3_EPU2-0/R36.4.3/Linux_for_Tegra/temp_initrdflash/bootloader0: No such file or directory
Cleaning up…

temp_initrdflash directory exists, but bootloader0 is missing every time

Should the script be creating bootloader0 automatically, or is there a step that I may be missing?

Any guidance would be greatly appreciated.

flashing command:

sudo BOARDID=3767 BOARDSKU=0000 FAB=300 ./tools/kernel_flash/l4t_initrd_flash.sh \
-u ./l4t/tools/flashtools/flash/rsa_priv.pem \
-v ./l4t/tools/flashtools/flash/sbk.key \
–external-device nvme0n1p1 \
-c tools/kernel_flash/flash_l4t_t234_nvme.xml \
-p “-c bootloader/generic/cfg/flash_t234_qspi.xml” \
–keep \
–showlogs \
–network usb0 \
jetson-orin-nano-devkit-super internal

hello OswaldUK,

this is created during the flashing process, and it is used for temporary bootloader files.

let’s narrow down the issue,
for instance, please check the readme file, $OUT/Linux_for_Tegra/tools/kernel_flash/README_initrd_flash.txt
you may refer to [Workflow 11: Generate images for internal device and external device seperately then flash] to create images for checking.

Thanks for pointing out Workflow 11 (specifically Example 2 for Orin NX). I have fixed the previous configuration error by modifying the .conf file to remove the _sd suffix, so the script now runs without the “SD card” error.

However, I have a critical question regarding the restoration process for a Fused Device:

When I run Step 2 of Workflow 11 (Generating the external file system), the script regenerates a fresh/stock system.imgfrom the rootfs directory, overwriting the custom raw system.img (my backup) that I placed in Linux_for_Tegra/bootloader/.

My Goal: I have a RAW system.img (unencrypted, restored from a backup). I need to flash this specific image to my FusedOrin NX. Since the target is Fused, I require Disk Encryption to be enabled.

Could you please provide the exact command sequence to:

  1. Generate/Sign the QSPI bootloader components.

  2. Take my existing custom RAW system.img (do not rebuild from rootfs).

  3. Encrypt this raw image using the provided keys (so it works with Disk Encryption).

  4. Flash the final package.

I am looking for something like: $ sudo ROOTFS_ENC=1 ... ./l4t_initrd_flash.sh ... --use-existing-image

What is the correct flag or workflow to pass an existing raw image to be encrypted and flashed without regeneration?

Thanks.

And I am trying to restore a custom RAW system.img (backup) to a Fused Orin NX 16GB (R36.4.3). I am using the “Generate → Swap Image → Flash” workflow (similar to Workflow 11) to avoid generating a new rootfs and to use my existing backup.

The Issue: The flashing process fails at Step 2 (Boot device) with a USB Timeout error when sending mb1.

Logs:
[ 0.0326 ] Sending bct_br
[ 0.0446 ] Sending mb1
[ 0.0453 ] ERROR: might be timeout in USB write.
Error: Return value 3
Command tegrarcm_v2 --instance 3-3 --new_session --chip 0x23 0 --uid --download bct_br br_bct_BR.bct --download mb1 mb1_t234_prod_aligned_sigheader_encrypt.bin.signed …

Hardware/Keys are verified: I confirmed that a standard secure flash (generating and flashing stock image in one go) WORKS SUCCESSFULLY. This rules out USB cable, Host PC, or Key mismatch issues. The QSPI state is clean.
Config is patched: I have already patched the .conf file to remove the _sd suffix, so the script correctly targets NVMe QSPI.

My Workflow:

Step 1: Generate (Success)

sudo BOARDID=3767 BOARDSKU=0000 FAB=300 ./tools/kernel_flash/l4t_initrd_flash.sh
-u keys/rsa_priv.pem -v keys/sbk.key
–external-device nvme0n1p1
-c tools/kernel_flash/flash_l4t_t234_nvme.xml
–no-flash --keep --network usb0
jetson-orin-nano-devkit-super internal

Step 2: Swap Image I replace the generated system.img (sparse/stock) in temp_initrdflash/images/ with my custom RAWsystem.img

Step 3: Flash Only (Fails)

sudo ./tools/kernel_flash/l4t_initrd_flash.sh
–flash-only --keep --network usb0
jetson-orin-nano-devkit-super internal

Question: Since standard flashing works, why does --flash-only result in a USB timeout at mb1 transfer? Could the size difference between the generated stock image (defined in XML during Step 1) and the swapped custom image cause the BootROM/Recovery mechanism to reject the transfer or time out?

hello OswaldUK,

as mentioned, we’re not support backup/restore a fused target’s image.
please have massflash process for your use-case.

Alright then,

I only want to encrypt my custom DTB files before performing a secure flash, so that they are properly encrypted during the process.

In order for them to be encrypted, into which directory under Linux_for_Tegra should I place my DTB files?

Or is there an easier method for encrypting DTB files?

hello OswaldUK,

you may try partition flash with no-flash options to create binary file locally.
please see-also $OUT/Linux_for_Tegra/tools/kernel_flash/README_initrd_flash.txt for [Workflow 9: Flash inidividual partition].
here’s demonstration to generate DTB file without flashing, you may add PKC/SBK keys for your use-case.
$ sudo BOARDID=3767 FAB=300 BOARDSKU=0003 ./tools/kernel_flash/l4t_initrd_flash.sh --no-flash --external-device nvme0n1p1 -c ./tools/kernel_flash/flash_l4t_external.xml -k A_kernel-dtb --external-only jetson-orin-nano-devkit-nvme nvme0n1p1

let me re-cap part of logs as below for reference.

*** Signing kernel_tegra234-p3768-0000+p3767-0003-nv.dtb ***                                                                                             
copying overlay_dtb(/home/jerry/nvidia/nvidia_sdk/JetPack_6.2.1_Linux_JETSON_ORIN_NANO_TARGETS/Linux_for_Tegra/kernel/dtb/L4TConfiguration.dtbo)... done.
copying overlay_dtb(/home/jerry/nvidia/nvidia_sdk/JetPack_6.2.1_Linux_JETSON_ORIN_NANO_TARGETS/Linux_for_Tegra/kernel/dtb/tegra234-carveouts.dtbo)... don
e.
copying overlay_dtb(/home/jerry/nvidia/nvidia_sdk/JetPack_6.2.1_Linux_JETSON_ORIN_NANO_TARGETS/Linux_for_Tegra/kernel/dtb/tegra-optee.dtbo)... done.
copying overlay_dtb(/home/jerry/nvidia/nvidia_sdk/JetPack_6.2.1_Linux_JETSON_ORIN_NANO_TARGETS/Linux_for_Tegra/kernel/dtb/tegra234-p3768-0000+p3767-0000-
dynamic.dtbo)... done.
...
./tegraflash.py --chip 0x23 --cmd "sign kernel_tegra234-p3768-0000+p3767-0003-nv.dtb kernel_dtb"   --boot_chain A  
*** kernel_tegra234-p3768-0000+p3767-0003-nv.dtb has been signed successfully. ***      

here’s path of the kernel-dtb binary file has created locally.

$ ll $OUT/Linux_for_Tegra/tools/kernel_flash/images/external/kernel_tegra234-p3768-0000+p3767-000*
-rw-r--r-- 1 root root 249517 Dec 11 09:49 tools/kernel_flash/images/external/kernel_tegra234-p3768-0000+p3767-0003-nv.dtb

Thanks, now I have flashed successfully couple times. But now I get this error:

Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Waiting for target to boot-up…
Timeout
Device failed to boot to the initrd flash kernel. Please retrive the serial log during flashing to debug further.
Cleaning up…

and sometimes I get this:

[ 0.0257 ] Sending bct_br
[ 0.0325 ] ERROR: might be timeout in USB write.
Error: Return value 3
Command tegrarcm_v2 --instance 3-6 --new_session --chip 0x23 0 --uid --download bct_br br_bct_BR.bct --download mb1 mb1_t234_prod_aligned_sigheader.bin.encrypt --download psc_bl1 psc_bl1_t234_prod_aligned_sigheader.bin.encrypt --download bct_mb1 mb1_bct_MB1_sigheader.bct.encrypt
Cleaning up...

i have tried 3 different host laptops, different usb ports, different usb cables, but the issue persists, do you have any clue or solution?

Thanks.