Compile custom image of Jetson Xavier AGX to SDK Manager

Hi all,

I have a Jetson Xavier AGX that I flashed with the SDK Manager.
After that, I compiled and installed all the necessary features to get it up and running for my specific purpose.

Now that I got a fully functional Jetson Xavier AGX according to my unique specifications I want to set up another one to be identical to the first (except for some key identifiers like IP for SSH, that I’ll change manually).

Is there a way I could generate/compile a custom image from my first Xavier to create an SDK Manager image?
I want to get the second Xavier up and running as fast as possible, and my first thought was to flash it with a custom SDK Manager Image generated from my first Xavier.

Any other means of accomplishing my goal, I am happy to hear your thoughts.

This is a slow process due to file sizes, but it is reasonably simple to do this.

First, you would clone the rootfs. The clone creates two files, the first of which is a “raw” file and is the exact byte size of the rootfs partition (e.g., if your filesystem is 28GB in size, then so is the raw image. The second file is the same image, but it is “sparse”. Sparse files are much smaller if the filesystem is not filled (they approach the size of raw if the filesystem approaches full capacity).

Raw files can be mounted on loopback and edited on the host PC. An example is editing ssh keys (which I happen to do), and perhaps udev rules based on a specific network MAC address. Firewall rules (if you’ve customized this) could also be edited. Then the raw file used for flashing.

I throw away the sparse file and keep only the raw file. Raw files and sparse files flash exactly the same way, and the only difference during flash is that the larger file takes longer. You can create a sparse file from the edited raw file using the “bootloader/mksparse” utility (the “-f 0” fill pattern, for NULL bytes, is what you’d use) if you so desire, but it isn’t worth doing unless you are going to flash several Jetsons. Note that you cannot edit a sparse file. If you are concerned about space, then after you are done you could use something like “bzip2 -9” on your raw file (takes a long time though).

To clone you can use most any release regardless of the release actually on the Jetson. To restore you must stick to the same release of flash software as that which originally created the cloned Jetson partition (there are some strong dependencies between boot content and the rootfs).

If you have used JetPack/SDKM before, then you will have this directory:
~/nvidia/nvidia_sdk/JetPack...version.../Linux_for_Tegra/

Within that is “flash.sh”. Note that most of the content of this directory is the “driver package”, and JetPack/SDKM is just a front end to this package…JetPack itself does not perform the flash. On recent releases you can create a clone via this while the Jetson is attached and in recovery mode:

sudo ./flash.sh -r -k APP -G my_backup.img jetson-xavier mmcblk0p1

The raw file produced would be “my_backup.img.raw”. The sparse file which I throw away would be “my_backup.img”. If you copy either of these to “Linux_for_Tegra/bootloader/system.img”, and then flash with the “-r” option to “reuse” the image, you’ll get what you want (you could edit the image prior to copying and flashing):
sudo ./flash.sh -r jetson-xavier mmcblk0p1

Note that this assumes the original image is the size of the default image. If you used a non-default image size, then you might also want to specify size with the “-S size” option. The raw image is the exact byte size of the partition, and the size would be evenly divisible by 1024 either twice or three times. If you take the size divided twice by 1024, then this is the size in MiB; if three times, then that is the size in GiB. For example, an image which is 30064771072 bytes divides three times by 1024 to “28”. This is option “-S 28 GiB”, and the above flash command to manually specify size becomes:
sudo ./flash.sh -r -S 28Gib jetson-xavier mmcblk0p1

The other partitions would be added in new, but these partitions are not custom unless you have a modification of device tree or other non-rootfs content, for example, due to using a third party carrier board. The instructions for those boards are very similar, in that you could replace or modify content within the “Linux_for_Tegra/” directory, and then that content would automatically be used during flash (you might need to alter your target from “jetson-xavier” to something the third party carrier board manufacturer designates).

Many people ask about just creating a single image and not flashing the other partitions, but this won’t work in most cases. Unless you go back quite some time those partitions are signed, and I don’t think the signature of one Jetson will work on another. There are ways to created signed partitions and save them for direct writing via something like dd on a running system, but it can be a bit of a pain and may differ in signature depending on which Jetson it goes to. Flashing those extra partitions is trivial in terms of time since they are tiny in comparison to the rootfs.

If you have a raw image and wish to examine or edit the image on your host PC, then you will need to cover it with loopback, and then mount the loop device. There are many ways to do this, but the easiest is to just let mount do this by passing the “-o loop” option. Example:

sudo mount -o loop ./my_backup.img.raw /mnt
cd /mnt
ls
# ...do stuff, edit things...
cd
sudo umount /mnt

…then copy the edited version to “Linux_for_Tegra/system.img” and flash with “-r”.

1 Like

Thank you!
I’ll look into this ASAP.