************************************************************************
             Examples of How to Use Image-Based OTA Update
************************************************************************
This file provides several examples of how to use image-based OTA update for
specific use cases.

Patches in this document are provided under the license terms of the files
they modify. Refer to patched files for license information.

1. Example of Modifying Intermediate Partition Layout
This example updates release 28.3 to release 32.6 on Jetson TX2. It assumes
that the release 28.3 default partition layout has been changed by adding one
64KB partition named test to the default partition layout
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186.xml, like this:
--- a/flash_l4t_t186.xml
+++ b/flash_l4t_t186.xml
@@ -416,6 +416,14 @@
             <allocation_attribute> 0x8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
         </partition>
+        <partition name="test" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>

Consequently, two default intermediate partition layouts in release 32.6:
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186_R28-3_R32i_emmc.xml
and
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186_R32A_R32i_emmc.xml,
must be modified.

Modify flash_l4t_t186_R28-3_R32i_emmc.xml like this:
--- a/flash_l4t_t186_R28-3_R32i_emmc.xml
+++ b/flash_l4t_t186_R28-3_R32i_emmc.xml
@@ -380,6 +380,14 @@
             <allocation_attribute> 0x8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
         </partition>
+        <partition name="test_rsv" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <!-- MSI EMMC start -->
         <partition name="MSI_EMMC_START" type="data">
             <allocation_policy> sequential </allocation_policy>
@@ -600,6 +608,14 @@
             <percent_reserved> 0 </percent_reserved>
             <filename> BOOTCTRL-FILE </filename>
         </partition>
+        <partition name="test" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>

Modify flash_l4t_t186_R32A_R32i_emmc.xml like this:
--- a/flash_l4t_t186_R32A_R32i_emmc.xml
+++ b/flash_l4t_t186_R32A_R32i_emmc.xml
@@ -544,6 +544,14 @@
             <description> **Optional.** Reserved for future use by the recovery filesystem;
               removable. </description>
         </partition>
+        <partition name="test" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <!-- MSI EMMC start -->
         <partition name="MSI_EMMC_START" type="data">
             <allocation_policy> sequential </allocation_policy>
@@ -762,6 +770,14 @@
             <allocation_attribute> 8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
         </partition>
+        <partition name="test_rsv" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>

Finally, the release 32.6 default partition layout must include the test
partition. Modify Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186.xml
in release 32.6, like this:
--- a/flash_l4t_t186.xml
+++ b/flash_l4t_t186.xml
@@ -560,6 +560,14 @@
             <description> **Optional.** Reserved for future use by the recovery filesystem;
               removable. </description>
         </partition>
+        <partition name="test" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>


2. Upgrade Release 32.3, 32.4, or 32.5 to Current Release with Partition Layout
Customization
Release 32.3, 32.4, and 32.5 use the same partition layout as the current
release, so an upgrade from any of those releases to the current one ordinarily
does not require partition layout changes. Partition layout changes are
necessary if you customize the old release or the current one or both in such a
way that their partition layouts are different.

For example, if you add two partitions named test and test_b before the kernel
partition in the 32.6 partition layout on Jetson TX2, an upgrade from an
unmodified release 32.4 requires you to make the following changes:

1) Modify Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186.xml in release
32.6 to  add the test and test_b partitions before kernel partition. The change
is like this:
@@ -508,6 +508,26 @@
             <filename> BOOTCTRL-FILE </filename>
             <description> **Required.** Slot B; contains boot control data. </description>
         </partition>
+        <partition name="test" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> For Test. </description>
+            <filename> test.bin </filename>
+        </partition>
+        <partition name="test_b" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> For Test. </description>
+            <filename> test.bin </filename>
+        </partition>
         <partition name="LNXNAME" type="data" oem_sign="true">
             <allocation_policy> sequential </allocation_policy>
<filesystem_type> basic </filesystem_type>

2) Create intermediate partition layout flash_l4t_t186_R32-4_R32i_emmc.xml
Copy the Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186.xml in the release 32.4
to Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186_R32-4_R32i_emmc.xml in
release 32.6 and then apply the following change:
@@ -519,14 +519,13 @@
             <description> **Required.** Slot A; contains U-Boot, which loads and launches the kernel
               from the rootfs at `/boot`. </description>
         </partition>
-        <partition name="LNXNAME_b" type="data" oem_sign="true">
+        <partition name="LNXNAME_b_rsv" type="data" oem_sign="true">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>
             <size> LNXSIZE </size>
             <file_system_attribute> 0 </file_system_attribute>
             <allocation_attribute> 8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
-            <filename> LNXFILE </filename>
             <description> **Required.** Slot B; contains U-Boot, which loads and launches the kernel
               from the rootfs at `/boot`. </description>
         </partition>
@@ -540,14 +539,13 @@
             <filename> KERNELDTB-FILE </filename>
             <description> **Required.** Slot A; contains kernel device tree blob. </description>
         </partition>
-        <partition name="KERNELDTB-NAME_b" type="data" oem_sign="true">
+        <partition name="KERNELDTB-NAME_b_rsv" type="data" oem_sign="true">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>
             <size> 524288 </size>
             <file_system_attribute> 0 </file_system_attribute>
             <allocation_attribute> 8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
-            <filename> KERNELDTB-FILE </filename>
             <description> **Required.** Slot B; contains kernel device tree blob. </description>
         </partition>
         <partition name="RECROOTFS" type="data">
@@ -560,6 +558,47 @@
             <description> **Optional.** Reserved for future use by the recovery filesystem;
               removable. </description>
         </partition>
+        <!-- MSI EMMC start -->
+        <partition name="MSI_EMMC_START" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <start_location> MSI_EMMC_OFFSET </start_location>
+            <size> 0 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
+        <partition name="test_b" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> For Test. </description>
+            <filename> test.bin </filename>
+        </partition>
+        <partition name="LNXNAME_b" type="data" oem_sign="true">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> LNXSIZE </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <filename> LNXFILE </filename>
+            <description> **Required.** Slot B; contains U-Boot, which loads and launches the kernel
+              from the rootfs at `/boot`. </description>
+        </partition>
+        <partition name="KERNELDTB-NAME_b" type="data" oem_sign="true">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 524288 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <filename> KERNELDTB-FILE </filename>
+            <description> **Required.** Slot B; contains kernel device tree blob. </description>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
<filesystem_type> basic </filesystem_type>

3) Create intermediate partition layout flash_l4t_t186_R32-4_R32A_R32i_emmc.xml
In the release 32.6, copy
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186.xml
to
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186_R32-4_R32A_R32i_emmc.xml.
And then apply the following change:
@@ -518,7 +518,7 @@
             <description> For Test. </description>
             <filename> test.bin </filename>
         </partition>
-        <partition name="test_b" type="data">
+        <partition name="test_b_rsv" type="data">
             <allocation_policy> sequential </allocation_policy>
             <filesystem_type> basic </filesystem_type>
             <size> 65536 </size>
@@ -526,7 +526,6 @@
             <allocation_attribute> 0x8 </allocation_attribute>
             <percent_reserved> 0 </percent_reserved>
             <description> For Test. </description>
-            <filename> test.bin </filename>
         </partition>
         <partition name="LNXNAME" type="data" oem_sign="true">
             <allocation_policy> sequential </allocation_policy>
@@ -580,6 +579,45 @@
             <description> **Optional.** Reserved for future use by the recovery filesystem;
               removable. </description>
         </partition>
+        <!-- MSI EMMC start -->
+        <partition name="MSI_EMMC_START" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <start_location> MSI_EMMC_OFFSET </start_location>
+            <size> 0 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+        </partition>
+        <partition name="test_b" type="data">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 65536 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 0x8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> For Test. </description>
+            <filename> test.bin </filename>
+        </partition>
+        <partition name="LNXNAME_b_rsv" type="data" oem_sign="true">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> LNXSIZE </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> **Required.** Slot B; contains U-Boot, which loads and launches the kernel
+              from the rootfs at `/boot`. </description>
+        </partition>
+        <partition name="KERNELDTB-NAME_b_rsv" type="data" oem_sign="true">
+            <allocation_policy> sequential </allocation_policy>
+            <filesystem_type> basic </filesystem_type>
+            <size> 524288 </size>
+            <file_system_attribute> 0 </file_system_attribute>
+            <allocation_attribute> 8 </allocation_attribute>
+            <percent_reserved> 0 </percent_reserved>
+            <description> **Required.** Slot B; contains kernel device tree blob. </description>
+        </partition>
         <partition name="UDA" type="data">
             <allocation_policy> sequential </allocation_policy>
<filesystem_type> basic </filesystem_type>

4) Create configuration file jetson-tx2-R32_4-R32i-emmc.conf
Copy Linux_for_Tegra/jetson-tx2-R32_1_2-R32i-emmc.conf to
Linux_for_Tegra/jetson-tx2-R32_4-R32i-emmc.conf, and replace the line:
EMMC_CFG=flash_l4t_t186_R32-1-2_R32i_emmc.xml
to
EMMC_CFG=flash_l4t_t186_R32-4_R32i_emmc.xml

5) Create configuration file jetson-tx2-R32_4-R32A-R32i-emmc.conf
Copy Linux_for_Tegra/jetson-tx2-R32_1_2-R32i-emmc.conf to
Linux_for_Tegra/jetson-tx2-R32_4-R32A-R32i-emmc.conf, and replace the line:
EMMC_CFG=flash_l4t_t186_R32-1-2_R32i_emmc.xml
to
EMMC_CFG=flash_l4t_t186_R32-4_R32A_R32i_emmc.xml

6) Create a new update control file
upgradetasklist.txt.jetson-tx2-devkit.R32-4_to_R32-ToT_emmc
Copy
Linux_for_Tegra/tools/ota_tools/version_upgrade/upgradetasklist.txt.jetson-tx2-devkit.R32-1-2_to_R32-ToT_emmc
to
Linux_for_Tegra/tools/ota_tools/version_upgrade/upgradetasklist.txt.jetson-tx2-devkit.R32-4_to_R32-ToT_emmc
And apply the following change:
@@ -32,52 +32,53 @@

 # <partition>: BCT, mb1, mb1_b, MB1_BCT, MB1_BCT_b, dram-ecc-fw, badpage-fw, badpage-fw_b, spe-fw, spe-fw_b, mb2, mb2_b, mts-preboo
ot, mts-preboot_b, SMD, SMD_b, secondary_gpt, master_boot_record, primary_gpt, APP, mts-bootpack, mts-bootpack_b, cpu-bootloader, cc
pu-bootloader_b, bootloader-dtb, bootloader-dtb_b, secure-os, secure-os_b, eks, adsp-fw, adsp-fw_b, bpmp-fw, bpmp-fw_b, bpmp-fw-dtbb
, bpmp-fw-dtb_b, sce-fw, sce-fw_b, sc7, sc7_b, FBNAME, BMP, BMP_b, recovery, recovery-dtb, kernel-bootctrl, kernel-bootctrl_b, kernn
el, kernel_b, kernel-dtb, kernel-dtb_b, secondary_gpt

-# <index file>: <directory of images>/<index file name>, such as R32-ToT/flash.idx, R32_1_2-R32i/flash.idx
+# <index file>: <directory of images>/<index file name>, such as R32-ToT/flash.idx, R32_3_4-R32i/flash.idx


-# Task list for upgrading from R32_1_2 to R32-ToT on Jetson-TX2
-# R32_1_2 includes R32.1 and R32.2
+# Task list for upgrading from R32_4 to R32-ToT on Jetson-TX2

 # Upgrade R32i for slot B1
-Update_B1:Write_BCT2:sdmmc_boot:BCT:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_boot:MB1_BCT_b:R32_1_2-R32i/flash.idx
+Update_B1:Write_BCT2:sdmmc_boot:BCT:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:MB1_BCT_b:R32_3_4-R32i/flash.idx

 # Write R32i
-Update_B1:Write:sdmmc_user:dram-ecc-fw:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:badpage-fw:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:spe-fw_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:mb2_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:mts-preboot_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:mts-bootpack_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:sc7_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:cpu-bootloader_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:bootloader-dtb_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:secure-os_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:eks:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:adsp-fw_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:bpmp-fw_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:bpmp-fw-dtb_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:sce-fw_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:kernel-dtb_b:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:recovery:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:recovery-dtb:R32_1_2-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:dram-ecc-fw:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:badpage-fw:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:spe-fw_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:mb2_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:mts-preboot_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:mts-bootpack_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:sc7_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:cpu-bootloader_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:bootloader-dtb_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:secure-os_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:eks:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:adsp-fw_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:bpmp-fw_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:bpmp-fw-dtb_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:sce-fw_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:kernel_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:kernel-dtb_b:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:recovery:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:recovery-dtb:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:test_b:R32_3_4-R32i/flash.idx
# Enable recovery mode by writing kernel-bootctrl image
-Update_B1:Set_Boot_Recovery_Mode:sdmmc_user:kernel-bootctrl:R32_1_2-R32i/flash.idx
-Update_B1:Set_Boot_Recovery_Mode:sdmmc_user:kernel-bootctrl_b:R32_1_2-R32i/flash.idx
+Update_B1:Set_Boot_Recovery_Mode:sdmmc_user:kernel-bootctrl:R32_3_4-R32i/flash.idx
+Update_B1:Set_Boot_Recovery_Mode:sdmmc_user:kernel-bootctrl_b:R32_3_4-R32i/flash.idx

-# Write MBR/GPTs for R32_1_2-R32i
-Update_B1:Write:sdmmc_boot:secondary_gpt:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:master_boot_record:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:primary_gpt:R32_1_2-R32i/flash.idx
-Update_B1:Write:sdmmc_user:secondary_gpt:R32_1_2-R32i/flash.idx
+# Write MBR/GPTs for R32_3_4-R32i
+Update_B1:Write:sdmmc_boot:secondary_gpt:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:master_boot_record:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:primary_gpt:R32_3_4-R32i/flash.idx
+Update_B1:Write:sdmmc_user:secondary_gpt:R32_3_4-R32i/flash.idx

 # Enable B path
-Update_B1:Set_Boot_Slot_B:sdmmc_user:SMD:R32_1_2-R32i/flash.idx
-Update_B1:Set_Boot_Slot_B:sdmmc_user:SMD_b:R32_1_2-R32i/flash.idx
+Update_B1:Set_Boot_Slot_B:sdmmc_user:SMD:R32_3_4-R32i/flash.idx
+Update_B1:Set_Boot_Slot_B:sdmmc_user:SMD_b:R32_3_4-R32i/flash.idx

 # Enable R32i B1
-Update_B1:Write:sdmmc_boot:mb1_b:R32_1_2-R32i/flash.idx
+Update_B1:Write:sdmmc_boot:mb1_b:R32_3_4-R32i/flash.idx

# Upgrade R32-ToT for slot A
Update_A:Clean_BCT1:sdmmc_boot:BCT:R32A-R32i/flash.idx
@@ -102,6 +103,7 @@ Update_A:Write:sdmmc_user:FBNAME:R32A-R3
 Update_A:Write:sdmmc_user:BMP:R32A-R32i/flash.idx
 Update_A:Write:sdmmc_user:kernel:R32A-R32i/flash.idx
 Update_A:Write:sdmmc_user:kernel-dtb:R32A-R32i/flash.idx
+Update_A:Write:sdmmc_user:test:R32A-R32i/flash.idx

 # Flash R32 recovery image/dtb in path A
 Update_A:Write:sdmmc_user:recovery:R32A-R32i/flash.idx
@@ -128,22 +130,9 @@ Update_A:Write_APP:sdmmc_user:APP:R32A-R
 # Upgrade R32-ToT for slot B2
 Update_B2:Write_BCT2:sdmmc_boot:BCT:R32-ToT/flash.idx
 Update_B2:Write:sdmmc_boot:MB1_BCT_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_boot:badpage-fw_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_boot:spe-fw_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_boot:mb2_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_boot:mts-preboot_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:mts-bootpack_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:cpu-bootloader_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:bootloader-dtb_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:secure-os_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:adsp-fw_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:bpmp-fw_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:bpmp-fw-dtb_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:sce-fw_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:sc7_b:R32-ToT/flash.idx
-Update_B2:Write:sdmmc_user:BMP_b:R32-ToT/flash.idx
 Update_B2:Write:sdmmc_user:kernel_b:R32-ToT/flash.idx
 Update_B2:Write:sdmmc_user:kernel-dtb_b:R32-ToT/flash.idx
+Update_B2:Write:sdmmc_user:test_b:R32-ToT/flash.idx
 Update_B2:Write:sdmmc_boot:mb1_b:R32-ToT/flash.idx

# Flash MBR and GPTs

7) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/ota_board_specs.conf like this:
@@ -79,6 +79,15 @@ JETSON_TX2_DEVKIT_R32_5_ALIAS="jetson_tx2_devkit_ota_emmc_r32_3_4_spec"
 # shellcheck disable=SC2034
 JETSON_TX2_DEVKIT_R32_6_ALIAS="jetson_tx2_devkit_ota_emmc_r32_3_4_spec"

+# For test r32.4 to latest release with layout change
+jetson_tx2_devkit_ota_emmc_r32_4_spec=(
+       'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=jetson-tx2-devkit;rootdev=mmcblk0p1;signed_img_dir=images-R32-ToT'
+       'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=jetson-tx2-R32_4-R32i-emmc;rootdev=mmcblk0p1;signed_img_dir=images-R32x-R32i'
+       'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=jetson-tx2-R32_4-R32A-R32i-emmc;rootdev=mmcblk0p1;signed_img_dir=images-R32A-R32i'
+)
+# shellcheck disable=SC2034
+JETSON_TX2_DEVKIT_R32_4_ALIAS="jetson_tx2_devkit_ota_emmc_r32_4_spec"

8) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/build_base_recovery_image.sh like this:
@@ -93,7 +93,7 @@ init()
        if [[ "${BASE_VERSION}" =~ "R28" ]]; then
                version="R28"
        else
-               if is_version_no_layout_change "${BASE_VERSION}"; then
+               if [ "${BASE_VERSION}" == "R32-4" ] || is_version_no_layout_change "${BASE_VERSION}"; then
                        version="R32_3_4"
                else
                        version="R32_1_2"

9) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh like this:
@@ -682,7 +682,11 @@ function generate_package()
        else
                storage_device="sd"
        fi
-       control_file_orig="upgradetasklist.txt.${TARGET_BOARD}.${version}_to_R32-ToT_${storage_device}"
+       if [ "${BASE_VERSION}" == "R32-4" ]; then
+               control_file_orig="upgradetasklist.txt.${TARGET_BOARD}.${BASE_VERSION}_to_R32-ToT_${storage_device}"
+       else
+               control_file_orig="upgradetasklist.txt.${TARGET_BOARD}.${version}_to_R32-ToT_${storage_device}"
+       fi
        if [ "${version}" == "R32_3_4" ]; then
                control_file_orig_A="upgradetasklist.txt.${TARGET_BOARD}.${version}_to_R32-ToT_slot_A_${storage_device}"
                control_file_orig_B="upgradetasklist.txt.${TARGET_BOARD}.${version}_to_R32-ToT_slot_B_${storage_device}"
@@ -704,6 +708,7 @@ function generate_package()
                "${OTA_DIR}/slot_metadata.bin.A"
                "${OTA_DIR}/slot_metadata.bin.B"
                "${BOOTLOADER_DIR}/bmp.blob"
+               "${BOOTLOADER_DIR}/test.bin"
        )

        t19x_binary_list=("${BOOTLOADER_DIR}/xusb_sil_rel_fw")
@@ -725,9 +730,11 @@ function generate_package()
                cp "${OTA_DIR}/kernel_bootctrl.bin.update" "${OTA_BASE_DIR_TMP}/${R32A_R32i_IMAGES_DIR}"
                cp "${OTA_DIR}/slot_metadata.bin.A" "${OTA_BASE_DIR_TMP}/${R32A_R32i_IMAGES_DIR}"
                cp "${BOOTLOADER_DIR}/bmp.blob" "${OTA_BASE_DIR_TMP}/${R32A_R32i_IMAGES_DIR}"
+               cp "${BOOTLOADER_DIR}/test.bin" "${OTA_BASE_DIR_TMP}/${R32A_R32i_IMAGES_DIR}"
                if [ -d "${OTA_BASE_DIR_TMP}/${base_r32i_dir}" ]; then
                        cp "${OTA_DIR}/kernel_bootctrl.bin.update" "${OTA_BASE_DIR_TMP}/${base_r32i_dir}"
                        cp "${OTA_DIR}/slot_metadata.bin.B" "${OTA_BASE_DIR_TMP}/${base_r32i_dir}"
+                       cp "${BOOTLOADER_DIR}/test.bin" "${OTA_BASE_DIR_TMP}/${base_r32i_dir}"
                fi
        fi

10) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/nv_ota_check_version.sh on both host machine and
target device like this:
@@ -188,7 +188,7 @@ get_ver_offset_in_recovery_kernel()
        else
                # If the OTA update has not been started yet, follow way of
                # getting offset of VER_b/VER partition in the base system
-               if is_version_no_layout_change "${base_version}"; then
+               if [ "${base_version}" == "R32-4" ] || is_version_no_layout_change "${base_version}"; then
                                get_ver_offset
                fi
        fi
@@ -456,7 +456,7 @@ ota_check_rollback()
        # 2. VER/VER_b partition will be re-located and written
        # 3. VER/VER_b partition will be written only.
        if ! is_recovery_kernel; then
-               if is_version_no_layout_change "${base_version}"; then
+               if [ "${base_version}" == "R32-4" ] || is_version_no_layout_change "${base_version}"; then
                        get_ver_offset
                fi
        else

11) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/nv_ota_common.func on both host machine and
target device like this:
@@ -25,7 +25,7 @@
 _BASE_RECOVERY_IMAGE=
 _BASE_RECOVERY_DTB=
 # Base versions without layout change
-_BASE_VERSIONS_NO_LAYOUT_CHANGE=( "R32-3" "R32-4" "R32-5" "R32-6" )
+_BASE_VERSIONS_NO_LAYOUT_CHANGE=( "R32-3" "R32-5" "R32-6" )
 _EXTLINUX_CONF_BACKUP="extlinux.conf.ota_backup"
 _K_BYTES=1024
 _NV_BOOT_CONTROL_CONF="nv_boot_control.conf"

12) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/nv_ota_update_with_layout_change.sh on
target device like this:
@@ -413,6 +413,14 @@ if [ "${BASE_VERSION}" == "R32-2" ] && [ "${TARGET_BOARD}" == "jetson-tx2-devkit
        fi
 fi

+if [ "${BASE_VERSION}" == "R32-4" ]; then
+       ota_log "write_kernel_bootctrl ${OTA_WORK_DIR} ${R32_IMAGES_DIR}"
+       if ! write_kernel_bootctrl "${OTA_WORK_DIR}" "${R32_IMAGES_DIR}"; then
+               ota_log "Failed to run \"write_kernel_bootctrl ${OTA_WORK_DIR} ${R32_IMAGES_DIR}\""
+               exit 1
+       fi
+fi

13) Modify Linux_for_Tegra/tools/ota_tools/version_upgrade/ota_check_partitions.sh on target device like this:
@@ -46,7 +46,7 @@ check_partition()
        version="$(cat "${work_dir}/base_version")"
        if [[ "${version}" =~ "R28" ]]; then
                base_r32i_dir="${work_dir}/${_R28_R32i_IMAGES_DIR}"
-       elif [ "${version}" == "R32-1" ] || [ "${version}" == "R32-2" ]; then
+       elif [ "${version}" == "R32-1" ] || [ "${version}" == "R32-2" ] || [ "${version}" == "R32-4" ]; then
                base_r32i_dir="${work_dir}/${_R32x_R32i_IMAGES_DIR}"
        elif is_version_no_layout_change "${version}"; then
                base_r32i_dir="${work_dir}/${_R32_TOT_IMAGES_DIR}"

14) Create the test.bin file that is to be written into the test/test_b partitions
under Linux_for_Tegra/bootloader by running the following commands:
$ cd Linux_for_Tegra/bootloader
$ echo "This is a test" >test.bin

3. ota-demo-host.sh and ota-demo-target.sh Sample Scripts
There are two pieces of sample code to demonstrate the complete image-based OTA
process. One, ota-demo-host.sh, is executed on the host machine to prepare the
OTA payload package. The other, ota-demo-target.sh, is executed on the target
device to start the OTA update process. The ota-demo-host.sh sample script must
be executed from the Linux_for_Tegra directory.

1) Sample code of ota-demo-host.sh
# This script is demo script running on the host machine to prepare
# OTA package
#
# It executes in following steps:
# 1. Get board spec from "ota_board_specs.conf".
# 2. Run the "build_base_recovery_image.sh" to generate recovery image and
#   recovery dtb.
# 3. Run the "l4t_generate_ota_package.sh" to the generate OTA package
#   "ota_payload_package.tar.gz".
# 4. Put the "ota_tools_R32.6.1_aarch64.tbz2" and the "ota_payload_package.tar.gz"
#   on the OTA server.

LINUX_BASE_DIR="$(pwd)"
OTA_DIR="${LINUX_BASE_DIR}/tools/ota_tools/version_upgrade"
BUILD_RECOVERY_IMG_DTB_SH="build_base_recovery_image.sh"
GENERATE_OTA_PACKAGE_SH="l4t_generate_ota_package.sh"
OTA_TOOLS_PACKAGE="${LINUX_BASE_DIR}/../ota_tools_R32.6.1_aarch64.tbz2"

# Set the OTA server path
# This is just an example. Please change it to
# your own OTA server path before running this script.
# For example:
OTA_SERVER_PATH="<user>@<ip address>:<ota path>"

usage ()
{
	echo -ne "Usage: sudo $0 [options] <target board> <bsp version> <base BSP L4T dir>\n"
	echo -ne "\tWhere,\n"
	echo -ne "\t\t<target board>: target board.\n"
	echo -ne "\t\t  Supported boards: jetson-tx2-devkit, jetson-agx-xavier-devkit, jetson-xavier-nx-devkit, jetson-xavier-nx-devkit-emmc, jetson-xavier-nx-devkit-tx2-nx.\n"
	echo -ne "\t\t<bsp version>: the version of the base BSP. Supported versions:R28-2, R28-3, R28-4, R32-1, R32-2, R32-3, R32-4, R32-5, R32-6;\n"
	echo -ne "\t\t<base BSP L4T dir>: the path of L4T dir of the base BSP;\n"
	echo -ne "\toptions:\n"
	echo -ne "\t\t-u <PKC key file>: PKC key used for odm fused board\n"
	echo -ne "\t\t-v <SBK key file>: Secure Boot Key (SBK) key used for ODM fused board\n"
	echo -ne "\t\t-s\tSkip generating system image.\n"
	echo -ne "\t\t-b\tUpdate bootloader only. Only valid for update without layout change.\n"
	echo -ne "\t\t-r\tUpdate rootfs only. Only valid for update without layout change.\n"
	echo -ne "\t\t-o\tSpecify the script for updating rootfs partition.\n"
	echo -ne "\t\t-f\tSpecify the path of rootfs image that is used to update rootfs partition.\n"
	echo -ne "Example:\n"
	echo -ne "\tsudo $0 -u PKCkeyfile -v SBKkeyfile jetson-tx2-devkit R28-3 <R28-3_BSP>/Linux_for_Tegra\n"
	exit 1

}

error_exit()
{
	echo "ERROR: ${1}"
	exit 1
}

# Make sure that this script is running in root privilege
USERID=$(id -u)
if [ "${USERID}" -ne 0 ]; then
       echo "Please run this program as root."
       exit 0
fi

if [ $# -lt 3 ];then
	usage
fi

PKC_KEY_FILE=""
SBK_KEY_FILE=""
skip_system_img=0
update_bl_only=0
update_rfs_only=0
rootfs_updater=
rootfs_image=
opstr+="bgrsu:v:o:f:"
while getopts "${opstr}" OPTION; do
	case $OPTION in
	u) PKC_KEY_FILE=${OPTARG}; ;;
	v) SBK_KEY_FILE=${OPTARG}; ;;
	s) skip_system_img=1; ;;
	b) update_bl_only=1; ;;
	r) update_rfs_only=1; ;;
	o) rootfs_updater=${OPTARG}; ;;
	f) rootfs_image=${OPTARG}; ;;
	*)
	   usage
	   ;;
	esac;
done

if [ "${PKC_KEY_FILE}" != "" ] && [ ! -f "${PKC_KEY_FILE}" ];then
	echo "Specified PKC key file \"${PKC_KEY_FILE}\" is not found"
	usage
fi

if [ "${SBK_KEY_FILE}" != "" ]; then
	if [ ! -f "${SBK_KEY_FILE}" ];then
		echo "Specified SBK key file \"${SBK_KEY_FILE}\" is not found"
		usage
	else
		if [ "${PKC_KEY_FILE}" == "" ]; then
			echo "PKC key must be provided once SBK key is specified"
			usage
		fi
	fi
fi

if [ "${update_bl_only}" == 1 ] && [ "${update_rfs_only}" == 1 ]; then
	echo "The option -b is conflicted with option -r"
	usage
fi

gen_ota_opts=""
if [ -n "${rootfs_updater}" ]; then
	if [ ! -r "${rootfs_updater}" ]; then
		echo "ERROR: The specified rootfs updater ${rootfs_updater} is not readable"
		usage
	else
		rootfs_updater="$(readlink -f "${rootfs_updater}")"
		gen_ota_opts+="-o ${rootfs_updater} "
	fi
fi

if [ -n "${rootfs_image}" ]; then
	if [ ! -r "${rootfs_image}" ]; then
		echo "ERROR: The specified rootfs image ${rootfs_image} is not readable"
		usage
	else
		rootfs_image="$(readlink -f "${rootfs_image}")"
		gen_ota_opts+="-f ${rootfs_image} "
	fi
fi

nargs=$#
BASE_L4T_DIR="${!nargs}"
nargs=$((nargs-1))
BASE_VERSION="${!nargs}"
nargs=$((nargs-1))
TARGET_DEVICE="${!nargs}"

KEY_FILE=""
if [ -f "${PKC_KEY_FILE}" ]; then
	KEY_FILE+="-u ${PKC_KEY_FILE} "
fi
if [ -f "${SBK_KEY_FILE}" ]; then
	KEY_FILE+="-v ${SBK_KEY_FILE} "
fi

# Generate recovery image and recovery dtb
echo "Generating recovery image and recovery dtb"
echo "${OTA_DIR}/${BUILD_RECOVERY_IMG_DTB_SH} ${KEY_FILE} ${TARGET_DEVICE} ${BASE_VERSION} ${BASE_L4T_DIR} ${BASE_L4T_DIR}/rootfs ${LINUX_BASE_DIR}"
if ! eval "${OTA_DIR}/${BUILD_RECOVERY_IMG_DTB_SH}" "${KEY_FILE}" "${TARGET_DEVICE}" "${BASE_VERSION}" "${BASE_L4T_DIR}" "${BASE_L4T_DIR}/rootfs" "${LINUX_BASE_DIR}"; then
	error_exit "Failed to run \"${OTA_DIR}/${BUILD_RECOVERY_IMG_DTB_SH} ${KEY_FILE} ${TARGET_DEVICE} ${BASE_VERSION} ${BASE_L4T_DIR} ${BASE_L4T_DIR}/rootfs ${LINUX_BASE_DIR}\""
fi

gen_ota_opts+="${KEY_FILE} "
if [ "${skip_system_img}" == 1 ]; then
	gen_ota_opts+="-s "
fi
if [ "${update_bl_only}" == 1 ]; then
	gen_ota_opts+="-b "
fi
if [ "${update_rfs_only}" == 1 ]; then
	gen_ota_opts+="-r "
fi

# Generate OTA package
echo "Generating OTA package"
echo "${OTA_DIR}/${GENERATE_OTA_PACKAGE_SH} ${gen_ota_opts} ${TARGET_DEVICE} ${BASE_VERSION}"
if ! eval "${OTA_DIR}/${GENERATE_OTA_PACKAGE_SH}" "${gen_ota_opts}" "${TARGET_DEVICE}" "${BASE_VERSION}"; then
	error_exit "Failed to run \"${OTA_DIR}/${GENERATE_OTA_PACKAGE_SH} ${gen_ota_opts} ${TARGET_DEVICE} ${BASE_VERSION}\""
fi

# Put OTA tools and OTA package onto OTA server
OTA_PAYLOAD_PACKAGE="${LINUX_BASE_DIR}/bootloader/${TARGET_DEVICE}/ota_payload_package.tar.gz"
echo "Putting OTA tools and OTA package onto OTA server"
scp "${OTA_TOOLS_PACKAGE}" "${OTA_SERVER_PATH}/"
SERVER="$(echo "${OTA_SERVER_PATH}" | cut -d: -f 1)"
PACKAGE_PATH="$(echo "${OTA_SERVER_PATH}" | cut -d: -f 2)"
# shellcheck disable=SC2029
ssh "${SERVER}" "mkdir -p ${PACKAGE_PATH}/${TARGET_DEVICE}/${BASE_VERSION}/"
scp "${OTA_PAYLOAD_PACKAGE}" "${OTA_SERVER_PATH}/${TARGET_DEVICE}/${BASE_VERSION}/"

echo "Finished"

2) Sample code of ota-demo-target.sh
# This script is demo for starting OTA process.
# It downloads the ota tool package and ota payload package, and then trigger
# the OTA process.

# Please edit the following configurations per your own environment
# For example:
OTA_DEMO_SERVER_PATH=http://example.com/partition_based_OTA
OTA_TOOL_PACKAGE_NAME="ota_tools_R32.6.1_aarch64.tbz2"
OTA_PAYLOAD_PACKAGE_NAME="ota_payload_package.tar.gz"
OTA_TOOL_PACKAGE_PATH=${OTA_DEMO_SERVER_PATH}/${OTA_TOOL_PACKAGE_NAME}
OTA_PAYLOAD_PACKAGE_PATH=${OTA_DEMO_SERVER_PATH}
OTA_TOOL_PATH="./Linux_for_Tegra/tools/ota_tools/version_upgrade"
OTA_START_SCRIPT="nv_ota_start.sh"

usage ()
{
	echo -ne "Usage: $0\n"
	exit 1
}

error_exit()
{
	echo "ERROR: ${1}"
	exit 1
}

# Make sure that this script is running in root privilege
USERID=$(id -u)
if [ "${USERID}" -ne 0 ]; then
       echo "Please run this program as root."
       exit 0
fi

# Get the board name and then the board name will be used to
# compose the full path of OTA payload package on the OTA server.
NV_BOOTCTRL_FILE="/etc/nv_boot_control.conf"
NV_BOOTCTRL_BOARD_NAME=""
NV_BOOTCTRL_BOARD_ID=""
NV_BOOTCTRL_BOARD_SKU=""
if [ ! -f "${NV_BOOTCTRL_FILE}" ]; then
	error_exit "${NV_BOOTCTRL_FILE} is not found"
else
	# The board name is included in the /etc/nv_boot_control.conf, so
	# the board id is used instead
	NV_BOOTCTRL_BOARD_ID="$(grep "^TNSPEC" <"${NV_BOOTCTRL_FILE}" | cut -d\  -f 2 | cut -d- -f 1)"
	if [ "${NV_BOOTCTRL_BOARD_ID}" == "" ]; then
		error_exit "Failed get board id from ${NV_BOOTCTRL_FILE}"
	fi
	if [ "${NV_BOOTCTRL_BOARD_ID}" == "3310" ]; then
		NV_BOOTCTRL_BOARD_NAME="jetson-tx2-devkit"
	elif [ "${NV_BOOTCTRL_BOARD_ID}" == "2888" ]; then
		NV_BOOTCTRL_BOARD_NAME="jetson-agx-xavier-devkit"
	elif [ "${NV_BOOTCTRL_BOARD_ID}" == "3668" ]; then
		# For jetson-xavier-nx, need to determine whether it is
		# jetson-xavier-nx-devkit or jetson-xavier-nx-devkit-emmc by
		# checking board sku
		NV_BOOTCTRL_BOARD_SKU="$(grep "^TNSPEC" <"${NV_BOOTCTRL_FILE}" | cut -d\  -f 2 | cut -d- -f 3)"
		if [ "${NV_BOOTCTRL_BOARD_SKU}" == "0000" ]; then
			NV_BOOTCTRL_BOARD_NAME="jetson-xavier-nx-devkit"
		elif [ "${NV_BOOTCTRL_BOARD_SKU}" == "0001" ]; then
			NV_BOOTCTRL_BOARD_NAME="jetson-xavier-nx-devkit-emmc"
		else
			error_exit "Board SKU(${NV_BOOTCTRL_BOARD_SKU}) is not supported"
		fi
	elif [ "${NV_BOOTCTRL_BOARD_ID}" == "3636" ]; then
		NV_BOOTCTRL_BOARD_NAME="jetson-xavier-nx-devkit-tx2-nx"
	else
		error_exit "Board ID(${NV_BOOTCTRL_BOARD_ID}) is not supported"
	fi
fi

# Get the version of current system and then the version will be used
# to compose the full path of OTA payload package on the OTA server.
NV_TEGRA_REL_FILE="/etc/nv_tegra_release"
NV_TEGRA_REL_BSP=""
NV_TEGRA_REL_REV_MAJOR=""
NV_TEGRA_REL_VER=""
if [ ! -f "${NV_TEGRA_REL_FILE}" ]; then
	error_exit "${NV_TEGRA_REL_FILE} is not found"
else
	NV_TEGRA_REL_BSP="$(grep -oE "[R0-9]+ \(release\)" <"${NV_TEGRA_REL_FILE}" | cut -d\  -f 1)"
	NV_TEGRA_REL_REV_MAJOR="$(grep -oE "REVISION: [0-9]" <"${NV_TEGRA_REL_FILE}" | cut -d\  -f 2)"
	NV_TEGRA_REL_VER="${NV_TEGRA_REL_BSP}-${NV_TEGRA_REL_REV_MAJOR}"
fi

# Download the OTA tool package
echo "Downloading OTA tool from ${OTA_TOOL_PACKAGE_PATH}"
if ! wget "${OTA_TOOL_PACKAGE_PATH}" -O "${OTA_TOOL_PACKAGE_NAME}"; then
	error_exit "Error: failed to download OTA tool package from ${OTA_TOOL_PACKAGE_PATH}"
fi

# Check the integrity of OTA tool package
echo "Checking the integrity of the OTA tool ${OTA_TOOL_PACKAGE_NAME}"
echo "bzip2 -t ${OTA_TOOL_PACKAGE_NAME}"
if ! bzip2 -t "${OTA_TOOL_PACKAGE_NAME}"; then
	error_exit "Error: the downloaded ${OTA_TOOL_PACKAGE_NAME} is broken"
fi

# Download the OTA payload package
# The full path of OTA payload package is:
#   ${OTA_PAYLOAD_PACKAGE_PATH}/${NV_BOOTCTRL_BOARD_NAME}/${NV_TEGRA_REL_VER}/${OTA_PAYLOAD_PACKAGE_NAME}
# For example, for upgrading R32.4.x to current release on jetson-tx2-devkit,
# the full path of OTA payload package is:
#   http://example.com/partition_based_OTA/jetson-tx2-devkit/R32-4/ota_payload_package.tar.gz
OTA_PAYLOAD_PACKAGE_PATH="${OTA_PAYLOAD_PACKAGE_PATH}/${NV_BOOTCTRL_BOARD_NAME}/${NV_TEGRA_REL_VER}/${OTA_PAYLOAD_PACKAGE_NAME}"
echo "Downloading OTA package from ${OTA_PAYLOAD_PACKAGE_PATH}"
if ! wget "${OTA_PAYLOAD_PACKAGE_PATH}" -O "${OTA_PAYLOAD_PACKAGE_NAME}"; then
	error_exit "Error: failed to download ota package from ${OTA_PAYLOAD_PACKAGE_PATH}"
fi

# Check the integrity of OTA payload package
echo "Checking the integrity of the OTA package ${OTA_PAYLOAD_PACKAGE_NAME}"
echo "gzip -t ${OTA_PAYLOAD_PACKAGE_NAME}"
if ! gzip -t "${OTA_PAYLOAD_PACKAGE_NAME}"; then
	error_exit "Error: the downloaded ${OTA_PAYLOAD_PACKAGE_NAME} is broken"
fi
OTA_PAYLOAD_PACKAGE_LOCAL_PATH="$(pwd)"/${OTA_PAYLOAD_PACKAGE_NAME}

# Untar OTA tool package
echo "tar xjvf ${OTA_TOOL_PACKAGE_NAME}"
if ! tar xjvf "${OTA_TOOL_PACKAGE_NAME}"; then
	error_exit "Failed untar ${OTA_TOOL_PACKAGE_NAME}"
fi

# Enter the OTA tool diretory
echo "pushd ${OTA_TOOL_PATH}"
pushd "${OTA_TOOL_PATH}" >/dev/null 2>&1 || error_exit "Failed to change directory to ${OTA_TOOL_PATH}"

# Trigger OTA process by calling script
echo "Triggering OTA process"
echo "./${OTA_START_SCRIPT} ${OTA_PAYLOAD_PACKAGE_LOCAL_PATH}"
if ! eval ./${OTA_START_SCRIPT} "${OTA_PAYLOAD_PACKAGE_LOCAL_PATH}"; then
	error_exit "Error: failed to trigger OTA process"
fi

# Leave the OTA tool diretory
echo "popd"
popd >/dev/null 2>&1 || error_exit "Failed to leave directory ${OTA_TOOL_PATH}"

echo "Device will reboot in 10 seconds. Press Ctrl+C to stop."
count=10
while [ $count -gt 0 ]
do
	echo -n "${count}..."
	sleep 1
	count=$((count - 1))
done
echo "Rebooting..."
sudo reboot

4. Upgrade on Customized Devices
If you create a customized device based on a Jetson carrier board, for example,
by adding a camera, you can still apply an image-based OTA update, but you must
make some additional changes. This section presents two examples of applying
image-based OTA on customized devices:

- An upgrade from release 28.4 to the current release on a customized device,
based on a Jetson TX2 carrier board, which requires partition layout changes.
The customized device’s configuration file is named customized-tx2-devkit.conf.
- An upgrade from release 32.4.3 to the current release on a customized device,
based on a Jetson Xavier NX carrier board, which does not require partition
layout changes. The customized device’s configuration file is named
customized-nx-devkit.conf.

1) Upgrade from r28.4 to the current release on a customized Jetson TX2
In this example a customized device is based on a Jetson TX2 carrier board. You
flash the customized device with a configuration file named
customized-tx2-devkit.conf, which you keep under the Linux_for_Tegra/ directory.
The customized-tx2-devkit.conf is needed for both r28.4 and the current release.
To generate the OTA payload package for this device, you must apply the
following changes to files under the Linux_for_Tegra  directory:

--- a/rootfs/opt/nvidia/l4t-bootloader-config/nv-l4t-bootloader-config.sh
+++ b/rootfs/opt/nvidia/l4t-bootloader-config/nv-l4t-bootloader-config.sh
@@ -78,7 +78,7 @@ jetson_tx1_devkit=(

 # shellcheck disable=SC2034
 jetson_tx2_devkit=(
-	"unify_name=jetson-tx2-devkit"
+	"unify_name=customized-tx2-devkit"
	"orig_name=p2597-0000+p3310-1000"
	"orig_name=jetson-tx2"
 )

--- a/tools/ota_tools/version_upgrade/nv_ota_check_version.sh
+++ b/tools/ota_tools/version_upgrade/nv_ota_check_version.sh
@@ -423,7 +423,7 @@ ota_check_rollback()
	fi

	case ${target_board} in
-		jetson-tx2-devkit)
+		jetson-tx2-devkit|customized-tx2-devkit)
			_BOOTDEV_SECTOR_SIZE=512
			_BCT_FILE_SIZE=3584
			_BCT_SLOT_SIZE=$(((_BCT_FILE_SIZE + _BOOTDEV_SECTOR_SIZE - 1) / _BOOTDEV_SECTOR_SIZE * _BOOTDEV_SECTOR_SIZE))

--- a/tools/ota_tools/version_upgrade/nv_ota_update_with_layout_change.sh
+++ b/tools/ota_tools/version_upgrade/nv_ota_update_with_layout_change.sh
@@ -41,6 +41,7 @@ R32_IMAGES_DIR="images-R32-ToT"
 MSI_EMMC_MIN_SIZE_TABLE=(
	# board:msi_emmc_min_size
	'jetson-tx2-devkit:134217728'    # 128MB
+	'customized-tx2-devkit:134217728'    # 128MB
	'jetson-agx-xavier-devkit:335544320' # 320MB
 )
 TARGET_BOARD=

--- a/tools/ota_tools/version_upgrade/ota_board_specs.conf
+++ b/tools/ota_tools/version_upgrade/ota_board_specs.conf
@@ -161,6 +161,7 @@ JETSON_XAVIER_NX_DEVKIT_TX2_NX_R32_6_ALIAS="jetson_xavier_nx_devkit_tx2_nx_ota_e
 T18X_DEVICES=(
	'JETSON_TX2_DEVKIT'
	'JETSON_XAVIER_NX_DEVKIT_TX2_NX'
+	'CUSTOMIZED_TX2_DEVKIT'
 )

 T19X_DEVICES=(
@@ -168,3 +169,12 @@ T19X_DEVICES=(
	'JETSON_XAVIER_NX_DEVKIT'
	'JETSON_XAVIER_NX_DEVKIT_EMMC'
 )
+
+# For test customized board with jetson-tx2-devkit
+customized_tx2_devkit_ota_emmc_r28_4_spec=(
+	'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=customized-tx2-devkit;rootdev=mmcblk0p1;signed_img_dir=images-R32-ToT'
+	'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=jetson-tx2-R28_4-R32i-emmc;rootdev=mmcblk0p1;signed_img_dir=images-R28-R32i'
+	'boardid=3310;fab=B01;boardsku=;boardrev=;fuselevel_s=1;chiprev=0;board=jetson-tx2-R32A-R32i-emmc;rootdev=mmcblk0p1;signed_img_dir=images-R32A-R32i'
+)
+# shellcheck disable=SC2034
+CUSTOMIZED_TX2_DEVKIT_R28_4_ALIAS="customized_tx2_devkit_ota_emmc_r28_4_spec"

--- a/tools/ota_tools/version_upgrade/ota_check_partitions.sh
+++ b/tools/ota_tools/version_upgrade/ota_check_partitions.sh
@@ -330,7 +330,7 @@ ota_check_partitions()
	local target_board=
	target_board="$(cat "${work_dir}/board_name")"
	case ${target_board} in
-		jetson-tx2-devkit|jetson-agx-xavier-devkit)
+		jetson-tx2-devkit|jetson-agx-xavier-devkit|customized-tx2-devkit)
			# check partitions on the boot device
			if ! check_sdmmc_boot_device "${work_dir}"; then
				ota_log "Error when checking boot device"

In addtition to applying above changes, you need to run the following commands:
$ cd Linux_for_Tegra/tools/ota_tools/version_upgrade
$ cp upgradetasklist.txt.jetson-tx2-devkit.R28_to_R32-ToT_emmc \
upgradetasklist.txt.customized-tx2-devkit.R28_to_R32-ToT_emmc

2) Upgrade from r32.4.3 to current release on customized-nx-devkit Device
In this example a customized device is based on a Jetson Xavier NX carrier board.
You flash the customized device with a configuration file named
customized-nx-devkit.conf, which you keep under the Linux_for_Tegra/ directory.
The customized-nx-devkit.conf is needed for both r32.4.3 and the current
release. To generate the OTA payload package for this device, you must apply the
following changes to files under the Linux_for_Tegra directory:

--- a/rootfs/opt/nvidia/l4t-bootloader-config/nv-l4t-bootloader-config.sh
+++ b/rootfs/opt/nvidia/l4t-bootloader-config/nv-l4t-bootloader-config.sh
@@ -144,9 +144,10 @@ jetson_xavier_as_xavier_nx=(

 # shellcheck disable=SC2034
 jetson_xavier_nx_devkit=(
-	"unify_name=jetson-xavier-nx-devkit"
+	"unify_name=customized-nx-devkit"
	"orig_name=p3509-0000+p3668-0000-qspi-sd"
	"orig_name=p3449-0000+p3668-0000-qspi-sd"
+	"orig_name=jetson-xavier-nx-devkit"
 )

 # shellcheck disable=SC2034

--- a/tools/ota_tools/version_upgrade/ota_board_specs.conf
+++ b/tools/ota_tools/version_upgrade/ota_board_specs.conf
@@ -167,4 +167,15 @@ T19X_DEVICES=(
        'JETSON_AGX_XAVIER_DEVKIT'
        'JETSON_XAVIER_NX_DEVKIT'
        'JETSON_XAVIER_NX_DEVKIT_EMMC'
+       'CUSTOMIZED_NX_DEVKIT'
 )
+
+# For test customized board with jetson-xavier-nx-devkit
+customized_nx_devkit_ota_sd_r32_4_spec=(
+       'boardid=3668;fab=100;boardsku=0000;boardrev=;fuselevel_s=1;chiprev=2;board=customized-nx-devkit;rootdev=mmcblk0p1;signed_img_dir=images-R32-ToT'
+
+       # A03 board - SD
+       'boardid=3668;fab=301;boardsku=0000;boardrev=;fuselevel_s=1;chiprev=2;board=customized-nx-devkit;rootdev=mmcblk0p1;signed_img_dir=images-R32-ToT'
+)
+# shellcheck disable=SC2034
+CUSTOMIZED_NX_DEVKIT_R32_4_ALIAS="customized_nx_devkit_ota_sd_r32_4_spec"
