How to create an SD card image for Jetson AGX Xavier

From RidgeRun Developer Wiki

Introduction

This wiki shows a small example on how to use NVIDIA's jetson-disk-image-creator.sh script to create an image that can be flashed to an SD card and used to boot a Jetson AGX Xavier.

This was tested using the script version for JetPack 4.6, but could be adapted for the JetPack 5.0+ version.

* Note: This is not officially supported and it's a "hacky" way of booting from an SD card. For this to work, the Jetson's eMMC has to be flashed first since some files are needed from there.

The disk image creator script

You can find this script in the ~/nvidia/nvidia_sdk/JetPack_*_TARGETS/Linux_for_Tegra/tools directory, created when you download some JetPack with the SDK Manager. If you run the script with the --help option, you will see the following:

********************************************
     Jetson Disk Image Creation Tool     
********************************************
Usage:
jetson-disk-image-creator.sh.backup -o <sd_blob_name> -b <board> -r <revision>
	sd_blob_name	- valid file name
	board		- board name. Supported boards are:
			   jetson-nano
			   jetson-nano-2gb-devkit
			   jetson-xavier-nx-devkit
	revision	- SKU revision number
			   jetson-nano: 100/200/300 for A01/A02/B00
			   jetson-nano-2gb-devkit: default
			   jetson-xavier-nx-devkit: default
Example:
jetson-disk-image-creator.sh.backup -o sd-blob.img -b jetson-nano -r 300
jetson-disk-image-creator.sh.backup -o sd-blob.img -b jetson-xavier-nx-devkit


You might notice that it only supports Jetson Nano and Jetson Xavier NX, but you can add support for Jetson AGX Xavier with some changes to this script and the nvptparser.py script, located in the same directory.

You can find more information about the jetson-disk-image-creator.sh script in Jetson developer guide - Flashing support - Flashing to an SD card.

How to add support for Jetson AGX Xavier

Since the jetson-disk-image-creator.sh script uses the flash.sh helper script, we can add an extra option for our platform and change how the arguments are passed to the flash.sh script as needed. You can find more information about this script here: Jetson developer guide - Flashing support - Flash Script Usage

You can use the following steps, used to add support for an AGX Xavier with CTI Rogue carrier board as an example:

1. Add the board to the function usage() function menu.

diff --git a/jetson-disk-image-creator.sh b/jetson-disk-image-creator.sh
index e8fdd7c..319a0b7 100755
--- a/jetson-disk-image-creator.sh
+++ b/jetson-disk-image-creator.sh
@@ -26,6 +26,7 @@ function usage()
        echo "                     jetson-nano"
        echo "                     jetson-nano-2gb-devkit"
        echo "                     jetson-xavier-nx-devkit"
+       echo "                     jetson-agx_xavier-cti_rogue"
        echo "  revision        - SKU revision number"
        echo "                     jetson-nano: 100/200/300 for A01/A02/B00"
        echo "                     jetson-nano-2gb-devkit: default"

2. Add the board revision number to the check_revision() function.

diff --git a/jetson-disk-image-creator.sh b/jetson-disk-image-creator.sh
index 319a0b7..4c8332c 100755
--- a/jetson-disk-image-creator.sh
+++ b/jetson-disk-image-creator.sh
@@ -68,6 +68,9 @@ function check_revision()
        jetson-nano-2gb-devkit)
                rev="300"
                ;;
+       jetson-agx_xavier-cti_rogue)
+               rev="400"
+               ;;
        esac
 }

3. Add the board information to the check_pre_req() function.

Here, the target variable should be the path to the .conf file for the board. For example, you can use target=jetson-agx-xavier-devkit for a Devkit carrier.

diff --git a/jetson-disk-image-creator.sh b/jetson-disk-image-creator.sh
index 4c8332c..619b99a 100755
--- a/jetson-disk-image-creator.sh
+++ b/jetson-disk-image-creator.sh
@@ -130,6 +130,11 @@ function check_pre_req()
                        target="jetson-xavier-nx-devkit"
                        storage="sdcard"
                        ;;
+               jetson-agx_xavier-cti_rogue)
+                       boardid="2888"
+                       target="jetson-agx-xavier-cti-rogue-base"
+                       storage="sdmmc_user"
+                       ;;
                *)
                        usage "Unknown board: ${board}"
                        ;;

4. Modify the command that creates signed images to specify the BOOTDEV environment variable and the root device. These variables should be added to all the other supported platforms so that the script remains usable for all of them.

diff --git a/jetson-disk-image-creator.sh b/jetson-disk-image-creator.sh
index 619b99a..b0e5c5c 100755
--- a/jetson-disk-image-creator.sh
+++ b/jetson-disk-image-creator.sh
@@ -118,22 +118,30 @@ function check_pre_req()
                        boardid="3448"
                        target="jetson-nano-qspi-sd"
                        storage="sdcard"
+                       root_dev="mmcblk0p1"
+                       boot_dev="mmcblk0p1"
                        ;;
                jetson-nano-2gb-devkit)
                        boardid="3448"
                        boardsku="0003"
                        target="jetson-nano-2gb-devkit"
                        storage="sdcard"
+                       root_dev="mmcblk0p1"
+                       boot_dev="mmcblk0p1"
                        ;;
                jetson-xavier-nx-devkit)
                        boardid="3668"
                        target="jetson-xavier-nx-devkit"
                        storage="sdcard"
+                       root_dev="mmcblk0p1"
+                       boot_dev="mmcblk0p1"
                        ;;
                jetson-agx_xavier-cti_rogue)
                        boardid="2888"
                        target="jetson-agx-xavier-cti-rogue-base"
                        storage="sdmmc_user"
+                       root_dev="mmcblk1p1"
+                       boot_dev="mmcblk1p1"
                        ;;
                *)
                        usage "Unknown board: ${board}"
@@ -187,7 +195,7 @@ function create_signed_images()
        rootfs_size=$((rootfs_size + (rootfs_size / 10)))
 
        # Generate signed images
-       BOARDID="${boardid}" BOARDSKU="${boardsku}" FAB="${rev}" BUILD_SD_IMAGE=1 "${l4t_dir}/flash.sh" "--no-flash" "--sign" "-S" "${rootfs_size}MiB" "${target}" "mmcblk0p1"
+       BOARDID="${boardid}" BOARDSKU="${boardsku}" FAB="${rev}" BUILD_SD_IMAGE=1 BOOTDEV="${boot_dev}" "${l4t_dir}/flash.sh" "--no-flash" "--sign" "-S" "${rootfs_size}MiB" "${target}" "${root_dev}"
        popd
 
        if [ ! -f "${bootloader_dir}/flashcmd.txt" ]; then

5. Modify the nvptparser.py script to set a default size in case none is passed.

diff --git a/nvptparser.py b/nvptparser.py
index b93e84a..39ccc39 100755
--- a/nvptparser.py
+++ b/nvptparser.py
@@ -21,7 +21,11 @@ def do_parse(config_file, storage):
     mbr = ()
     for p in tree.findall("./device[@type='%s']/partition" % storage):
         name = p.get('name')
-        size = p.find('size').text.strip()
+        size = p.find('size')
+        if (size is not None):
+            size = size.text.strip()
+        else:
+            size = 134217728
         found = p.find('filename')
         if found is not None:
             filename = found.text.strip()

6. Once you apply the previous changes, you can run the script to create the image:

sudo ./jetson-disk-image-creator.sh -o my-sd-card-image.img -b jetson-agx_xavier-cti_rogue

Make sure to use the name of the target board that you added, in this case: jetson-agx_xavier-cti_rogue.

How to flash the SD card

NVIDIA recommends using Etcher for Linux to flash to an SD card, since it is very simple, but you can also use the dd command. You can find information on how to use both tools here: Jetson developer guide - Flashing support - Flashing to an SD card.