Jetson Nano/TX1 Update and Redundancy

Applies to: Jetson Nano devices and Jetson TX1
The NVIDIA® Jetson™ Nano and NVIDIA Jetson TX1 platforms use the Debian package facility to update Bootloader. The Bootloader update process performs Bootloader updates safely and ensures that a usable Bootloader partition exists at all times during an update.
Note:
Before you study this topic you must become familiar with the following topics:
Information about the Jetson platform may be found in the NVIDIA Developer Center at:

TegraBoot and Partition Layout

The BCT is stored in a partition named BCT. The NVIDIA flashing utility tegraflash.py writes up to 64 instances of the BCT, depending on the amount of space allocated for the BCT partition. Instances are aligned on consecutive 16 KiB boundaries.
The NVIDIA® Tegra® BootROM validates the BCT through an integrated checksum or RSA signature. If the calculated checksum or signature does not match the value in the BCT located at the beginning of the partition, the BootROM attempts to validate the next instances of the BCT. If the checksum or signature again does not match, the BootROM attempts to validate the next instance, and so on, until it finds a valid instance of the BCT or exhausts the available instances.
On platforms that boot from eMMC memory (Jetson TX1, the Jetson Nano 4GB production module, and a Jetson Nano developer kit module that is used with an SD card), L4T uses two groups of files to implement redundancy:
A boot-file-set (BFS) is a set of all of the files in a group of partitions that are concerned with booting. TegraBoot files are not part of a BFS, since BootROM loads TegraBoot, the TegraBoot loads the BFS.
A kernel-file-set (KFS) is a set of all of the files in a group of partitions that are concerned with loading the kernel.
The partitions included in a BFS and a KFS are listed in the section Redundancy Boot Firmware.
A BCT can contain two entries that indicate the locations (offset and size) and checksums or signatures for TegraBoot, the boot files, and the kernel files. The BootROM computes and validates the checksums or signatures for each TegraBoot entry. When it finds a valid set of checksums or signatures, it transfers control to the specified instance of TegraBoot.
TegraBoot computes and validates the checksums for the first BFS and the first KFS and the signatures the individual files. When the checksums and signatures have been validated, TegraBoot loads the appropriate boot files, such as:
The TegraBoot CPU binary
DTB files used by Bootloader
DTB files used by the kernel
Warmboot binary
Trusted OS image
When all necessary boot files have been verified and loaded, TegraBoot transfers control to the boot loader, e.g. CBoot. The boot loader validates and loads the next-level software component, such as the Linux kernel or U‑Boot.
If TegraBoot fails to validate the first BFS andKFS, it overwrites itself and resets the board so that the BootROM can validate and load the next set of TegraBoot, BFS, and KFS.
Note:
When Jetson Nano boots from an SD card it doesn’t use redundancy to load the BFS and KFS. It only uses the redundant TegraBoot partition (partition NVC). Because the partitions used by Bootloader are on the SD card, it is easy to replace the SD card to restore a corrupted Bootloader.

Redundancy Boot Firmware

The partition configuration file contains partitioning information for both the Tegra partition table and the GPT. They are at these locations:
For Jetson TX1: bootloader/t210ref/cfg/gnu_linux_fastboot_emmc_full.xml
For a Jetson Nano 4GB production module (with eMMC storage): bootloader/t210ref/cfg/flash_l4t_t210_emmc_p3448.xml
For a Jetson Nano development module (with Micro SD storage): bootloader/t210ref/cfg/flash_l4t_t210_spi_sd_p3448.xml
The redundancy layout must contain these partitions, in order:
1. Boot partitions, which are used in the boot process, and are visible only to Bootloader.
Many of the boot partitions have redundant copy partitions. The copy partitions must have the same names as their primaries with the suffix ‘‑1’. For example, the NVC partition’s copy must be named NVC‑1.
The boot partitions are:
BCT, which contains redundant instances of the Boot Configuration Table. This must be the first partition on the boot device.
NVC contains TegraBoot. This must be the second boot partition. The following boot partitions, PT through SPF, are part of the BFS.
PT contains layout information for each BFS, and indicates the beginning of each one. It is the first partition in the BFS.
TBC contains the TegraBoot CPU-side binary.
RP1 contains TegraBoot DTBs.
EBT contains CBoot.
WB0 contains the warm boot binary.
BPF contains BPMP microcode.
NVC‑1 contains a copy of NVC.
PT‑1 through BPF‑1 are copy partitions for the primaries NVC through BPF, making up a copy of the BFS, denoted BFS‑1.
PAD is an empty partition which ensures the VER and VER_b are at the very end of the boot partition.
VER_b contains additional version information for redundancy and version checking.
VER contains version information.
2. GP1 contains the sdmmc_user device’s primary GPT. All partitions defined after this one are configured in the Linux kernel, and are accessible by standard partition tools such as gdisk and parted.
3. User partitions, which have a variety of uses. Some of them may be deleted, and/or may be mounted and used to store application files.
The following partitions constitute the kernel-file-set (KFS), and have redundant copy partitions:
DTB contains kernel DTBs.
TOS contains the trusted OS binary.
EKS is optional, and is reserved for future use.
LNX contains either the Linux kernel or U-Boot, depending on your choice of DFLT_KERNEL_IMAGE in the configuration file.
DTB‑1 through EKS‑1 constitute a copy of the primary KFS, denoted KFS‑1.
Other partitions, such as APP and BMP, are outside the scope of this document. For information about these partitions, see the appropriate subsection for your Jetson platform in Default Partition Overview.
In summary, the overall layout for a partition configuration file is:
BCT
NVC
Boot-file-set (BFS): PT, TBC, RP1, EBT, WB0, BPF
NVC-1
Boot-file-set copy (BFS-1): PT-1, TBC-1, RP1-1, EBT-1, WB0-1, BPF-1
PAD
VER_b
VER
GP1
APP (not described here)
Kernel-file-set (KFS): DTB, TOS, EKS, LNX
Kernel-file-set copy (KFS-1): DTB-1, TOS-1, EKS-1, LNX-1
BMP and others (not described here)
While the kernel is booting, the boot partitions are available subject to write protection on these devices:
Partition
Device Name
BCT, NVC, and BFS
/dev/mmcblk0boot0
NVC‑1, BFS‑1, VER_b, and VER
/dev/mmcblk0boot1
Unlike BFS, all KFS partitions are visible from Linux on these devices:
Partition
Device Name
DTB
/dev/disk/by-partlabel/DTB
TOS
/dev/disk/by-partlabel/TOS
EKS
/dev/disk/by-partlabel/EKS
LNX
/dev/disk/by-partlabel/LNX
DTB-1
/dev/disk/by-partlabel/DTB-1
TOS-1
/dev/disk/by-partlabel/TOS
EKS-1
/dev/disk/by-partlabel/EKS-1
LNX-1
/dev/disk/by-partlabel/LNX-1

Generating the Bootloader Update Payload (BUP)

A Bootloader Update Payload (BUP) is used to implement bootloader update. It contains firmware binaries of each type needed to update a Jetson device. You generate it on the host with build_l4t_bup.sh, which is packaged along with flash.sh in the Linux for Jetson Board Support Package (BSP).
This section describes procedures for generating a multi-spec BUP or a single-spec BUP. A multi-spec BUP includes multiple firmware binaries and BCT images of each type, and can be used to update any supported type of Jetson device. When you run the updater, it uses the appropriate binary of each type for the device you are updating. A single-spec BUP contains just one binary of each type, and can be used to update just one Jetson device configuration.
To generate a multi-spec BUP
Enter the commands:
$ cd <top>
$ sudo ./l4t_generate_soc_bup.sh [-u <pkc_key_file>] [‑p <options>] [-d] <processor>
Where:
<top> is the pathname of the directory that contains the PDK installation package. The flash.sh script is in this directory.
<pkc_key_file> is the RSA private key file for your Jetson carrier board. If it is a relative pathname, it is interpreted relative to the <top>/bootloader directory.
<options> is a string containing command line options to be passed to flash.sh to generate the BUP. If the string contains whitespace characters, it must be enclosed in quotes.
-d causes the script to run in debug mode, which keeps all boot firmware blob images in bootloader/signed and bootloader/multi-signed.
<processor> is t21x for a Jetson Nano device or a Jetson TX1 device.
The procedure stores the BUP in the file:
<top>/bootloader/<payload_dir>/bl_update_payload
Where <payload_dir> is a directory for BUPs that apply to a specific type of Jetson or Tegra processor. For more information, see Where the BUP File is Stored, below.
To generate a single-spec BUP
Enter the command:
$ sudo [env={value}, …] ./build_l4t_bup.sh [<options>] <board> <rootdev>
Where:
<options> is a string containing command line options to be passed to flash.sh to generate the BUP. If the string contains whitespace characters, it must be enclosed in quotes.
<board> is the value of $(BOARD) for your Jetson module and configuration, as shown in the table Jetson Modules and Configurations in the topic Quick Start.
<rootdev> is the partition where the root file system is to be flashed.
The procedure stores the BUP in the file:
<top>/bootloader/<payload_dir>/bl_update_payload
Where <payload_dir> is a directory for BUPs that apply to a specific type of Jetson or Tegra® processor. For more information, see Where the BUP File is Stored, below.
Where the BUP File is Stored
Both procedures store the BUP file at:
<top>/bootloader/<payload_dir>/bl_update_payload
Where <payload_dir> for Jetson Nano and Jetson TX1 devices is payloads_t21x.
You must place the BUP file in the target system under this directory before the Update Engine is run:
/opt/ota_package/
Location and Functions of Generated BUP Files
The procedure generates these BUPs in the directory <top>/bootloader/payloads_t21x:
bl_update_payload: Contains all required binaries.
xusb_only_payload: Contains xusb.
For a Jetson Nano device booting from an SD card, the procedure generates these additional BUPs:
bl_only_payload: Contains the bootloader binaries.
kernel_only_payload: Contains the kernel and kernel DTB.
porg_qspi_only_payload: Contains binaries stored in QSPI memory.
porg_sd_only_payload: Contains binaries stored on the SD card.
To use new Bootloader firmware to generate the BUP
Copy the corresponding bootloader firmware binaries to replace the ones in <top>/bootloader/t210ref/, then run l4t_generate_soc_bup.sh to generate the new BUP.
To print out the BUP’s header information and entry tables
Enter these commands:
$ cd <top>/bootloader
$ ./BUP_generator.py -c payloads_t21x/bl_update_payload

Bootloader Update

The update tool is /user/sbin/l4t_payload_updater_t210/. You can use it to update all partitions contained in the BUP.
To update the BUP
Enter this command:
$ sudo l4t_payload_updater_t210 payloads_t21x/bl_update_payload
The script stores the bootloader update log in /opt/ota_package/bl_update_payload.log.
Note:
The Bootloader Debian package nvidia-l4t-bootloader_32.3.0-xxx_arm64.deb uses this script to perform the Bootloader update automatically.
To print out device’s bootloader version
Enter this command:
$ sudo l4t_payload_updater_t210 -v
The command prints a message like this one:
# R32 , REVISION: 3.0

Bootloader Update Flow

The script /user/sbin/l4t_payload_updater_t210 implement the full Bootloader update process.
The following diagram shows the Bootloader update flow from BootROM to BCT, to NVC, to BFS, to KFS.
1. Before updating the partitions look like this.
2. Update BCT_64, BFS‑1, KFS‑1, and NVC‑1.
In the normal boot-up process, BootROM searches for the valid BCT upward from BCT_1. In the Bootloader update process, the updater doesn’t know which BCT is valid, so to keep the good path it searches downward from BCT_64. Thus an update failure on any partition does not affect the good path, BootROM → BCT_1 (or BCT_xx) → NVC → BFS → KFS.
A diagram of a network Description automatically generated
3. Update from BCT_63 down to BCT_1.
A diagram of a network Description automatically generated
4. Update BFS and KFS.
A diagram of a computer Description automatically generated
5. Update NVC.
NVC is updated last so as not to enable the BCT_1 → NVC and BCT_2 → NVC paths before the BFS path is ready.
A diagram of a computer Description automatically generated

Sample Logs in BUP Generation, Boot, and Update for BFS/KFS

This section contains examples of logs for common BUP generation, booting, and boot updating cases. They can be used to check whether errors happened in these operations.
Sample Logs in BUP Generation about BFS/KFS
This log shows the BFS/KFS information used in BUP generation, such as binary name, size and BFS/KFS checksum.
[ 0.2271 ] Updating BFS information on BCT
[ 0.2285 ] tegrabct --bct P2180_A00_LP4_DSC_204Mhz.bct --chip 0x21 0 --updatebfsinfo flash.xml.bin
[ 0.2294 ] BFS:
[ 0.2311 ] 0: [PT ] flash.xml.bin (size=4626/16384)
[ 0.2333 ] 1: [TBC] nvtboot_cpu.bin.encrypt (size=65856/172032)
[ 0.2364 ] 2: [RP1] tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb.encrypt (size=490480/1007616)
[ 0.2379 ] 3: [EBT] cboot.bin.encrypt (size=484304/999424)
[ 0.2383 ] 4: [WB0] warmboot.bin.encrypt (size=3952/8192)
[ 0.2387 ] 5: [BPF] sc7entry-firmware.bin.encrypt (size=3376/8192)
[ 0.2394 ] 6: [TOS] tos-mon-only.img.encrypt (size=54208/557056)
[ 0.2398 ] BFS0: 16384 @ 2784 SUM 7b64c63a over 2768896 bytes
[ 0.2402 ] BFS:
[ 0.2403 ] 0: [PT-1] flash.xml.bin (size=4626/16384)
[ 0.2412 ] 1: [TBC-1] nvtboot_cpu.bin.encrypt (size=65856/172032)
[ 0.2418 ] 2: [RP1-1] tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb.encrypt (size=490480/1007616)
[ 0.2425 ] 3: [EBT-1] cboot.bin.encrypt (size=484304/999424)
[ 0.2431 ] 4: [WB0-1] warmboot.bin.encrypt (size=3952/8192)
[ 0.2453 ] 5: [BPF-1] sc7entry-firmware.bin.encrypt (size=3376/8192)
[ 0.2458 ] 6: [TOS-1] tos-mon-only.img.encrypt (size=54208/557056)
[ 0.2463 ] BFS1: 16384 @ 8928 SUM 7b64c63a over 2768896 bytes
[ 0.2468 ] KFS:
[ 0.2618 ] 0: [DTB] tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb.encrypt (size=490480/503808)
[ 0.2626 ] 1: [LNX] boot.img.encrypt (size=495616/67092480)
[ 0.2631 ] KFS0: 503808 @ 29376546 SUM 22c0f1c4 over 999424 bytes
[ 0.2666 ] KFS:
[ 0.2915 ] 0: [DTB-1] tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb.encrypt (size=490480/503808)
[ 0.2923 ] 1: [LNX-1] boot.img.encrypt (size=495616/67092480)
[ 0.2928 ] KFS1: 503808 @ 29508730 SUM 22c0f1c4 over 999424 bytes
 
Sample Logs in TegraBoot about BFS/KFS
This log shows which BFS/KFS copy the device booted with.
In the normal case, the device boots from BFS0 and KFS0:
...
*** Booting BFS0.
...
*** Booting KFS0.
...
If BFS0 or KFS0 boot failed, switch to boot from BFS1 and KFS1:
Example 1:
...
*** Failing over to BFS1.
...
*** Booting BFS1.
*** Booting KFS1.
...
Example 2:
...
*** Failing over to KFS1.
...
*** Booting BFS1.
*** Booting KFS1.
...
Sample Logs from Bootloader Update
This log shows messages that appear during bootloader update, including BUP header, entries, and update sequence.
BLOB PATH:
/opt/payloads_t21x/bl_update_payload
 
[R]eading 65,536 bytes of /dev/mmcblk0boot1 at offset 4,128,768
VER number: 320300
[R]eading 65,536 bytes of /dev/mmcblk0boot1 at offset 4,063,232
VER_b number: 320300
blob ver number: 320300
[R]eading 376,832 bytes of /dev/mmcblk0boot0 at offset 1,048,576
[R]eading 376,832 bytes of /dev/mmcblk0boot1 at offset 0
BLOB HEADER:
Magic: NVIDIA__BLOB__V2
Version: 0x00020000
Blob Size: 9,405,126 bytes
Header Size: 40 bytes
Entry Count: 56 partition(s)
Type: 0 (0 for update, 1 for BMP)
Uncompressed
Blob Size: 9,405,126 bytes
Accessory: Not Present
 
ENTRY TABLE:
| part_name | offset | part_size | version | op_mode | tnspec |
| VER_b | 2393331 | 83 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| BCT64 | 6760 | 10240 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| NVC-1 | 2394006 | 173344 | 2 | 0 | |
| PT-1 | 2363832 | 4626 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| TBC-1 | 2567350 | 65856 | 2 | 0 | |
| RP1-1 | 88680 | 490480 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| EBT-1 | 2633206 | 484304 | 2 | 0 | |
| WB0-1 | 3117510 | 3952 | 2 | 0 | |
| BPF-1 | 3121462 | 3376 | 2 | 0 | |
| TOS-1 | 3124838 | 54208 | 2 | 0 | |
| DTB-1 | 3251062 | 490480 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| LNX-1 | 5526214 | 495616 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| EKS-1 | 3179046 | 1028 | 2 | 0 | |
| BCT63 | 6760 | 10240 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
....
| BCT2 | 6760 | 10240 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| BCT | 6760 | 10240 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| PT | 2363832 | 4626 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| TBC | 2567350 | 65856 | 2 | 0 | |
| RP1 | 88680 | 490480 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| EBT | 2633206 | 484304 | 2 | 0 | |
| WB0 | 3117510 | 3952 | 2 | 0 | |
| BPF | 3121462 | 3376 | 2 | 0 | |
| TOS | 3124838 | 54208 | 2 | 0 | |
| DTB | 3251062 | 490480 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| LNX | 5526214 | 495616 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| EKS | 3179046 | 1028 | 2 | 0 | |
| NVC | 2394006 | 173344 | 2 | 0 | |
| VER | 2393331 | 83 | 2 | 0 | 2180-100---1-0-jetson-tx1-mmcblk0p1 |
| BMP | 3180074 | 70988 | 2 | 0 | |
Note: only partitions updatable on this system are shown, use "-p" to show all partitions in payload.
Note: partitions are written to system top down in the order shown above.
 
Beginning update.
 
Updating partition: VER_b
[R]eading 83 bytes of /dev/mmcblk0boot1 at offset 4,063,232
[E]rasing 65,536 bytes to /dev/mmcblk0boot1 at offset 4,063,232
[W]riting 83 bytes to /dev/mmcblk0boot1 at offset 4,063,232
[R]eading 83 bytes of /dev/mmcblk0boot1 at offset 4,063,232
Verification successful.
 
…... (Updating all partitions) ……
 
Total data updatable for system: 89 partitions, 5,261,054 bytes.
Total data written to system: 68 partitions, 664,778 bytes.
 
Update successful.