I will add some information for clarification, but not a complete answer: If the boot environment is “standard”, then flashing will install this simply by flashing with the correct release. If not (e.g., custom device tree for a third party carrier board), then this can be put in place on the host PC such that you flash on command line and name the right configuration and it will use your content. The rootfs image can be “reused” such that an image you put there is flashed rather than generating a new default image does not occur, and the two of those together will be “everything” if your rootfs image is a clone from some reference system you’ve tested.
Note that when you flash on command line and name a target, e.g., “jetson-xavier-nx-devkit
”, then it is essentially referring to the .conf
file of the same name, “jetson-xavier-nx-devkit.conf
”. Those conf files basically refer to a combination of carrier board configuration and module configuration, and are human readable. You could copy this and create your own target for flash whereby the existing module config is unmodified, but in which you name a custom device tree (the carrier board config part). Explore the .conf
files.
The rootfs, by default, is just the Ubuntu image along with NVIDIA drivers. This is what gets flashed (mostly this is just a copy of “Linux_for_Tegra/rootfs/
”, but some of the "rootfs/boot/
" content is updated right before rootfs image creation depending on the flash target (e.g., the flash content might need to name a different device tree depending on whether it is an NX dev kit or an AGX dev kit). The addition of optional software, e.g., CUDA, only occurs after the flash is complete via ssh
on a fully running system, so this part will not be found in “rootfs/
”.
To get an image with everything, then I suggest you start with a pristine flash, run the update (“sudo apt update
” and “sudo apt-get upgrade
”), followed by adding your custom software (the addition by JetPack/SDK Manager of CUDA and its options could occur in between flash and your software additions). Then clone this and use that image for “reuse” when flashing.
Do beware though that everything is copied when cloning. This means that if you’ve created a login account, then that gets cloned too. If you leave temp files behind, then those get cloned. If you’ve set up network, including any use of a specific MAC address, then this gets cloned. You can easily loopback mount the raw clone and edit if you know what to edit, and normally the only thing that matters would be the passwords and accounts, but you would need to be careful.
The clone produces both a raw backup, and a sparse backup. The raw file is the exact size and content of the partition from the clone (an enormous file which takes significant time even to copy it), and can be loopback mounted, examined, edited, so on. The sparse file is for flashing only, and I normally throw this file away. The application “Linux_for_Tegra/bootloader/mksparse
” can create a sparse version at any time (e.g., “mksparse -v --fillpattern=0 system.img.raw system.img
”). The flash can use either version without any change simply by placing it at “bootloader/system.img
”, but the sparse version is much smaller (sparse is the size of the underlying files instead of the partition as a whole, so as file content approaches a full file system the sparse image approaches the size of the full partition just like the raw image). The smaller image means faster flash.
An example clone for an NX dev kit to create both raw and sparse clone from the SD card model:
sudo ./flash.sh -r -k APP -G my_backup.img jetson-xavier-nx-devkit mmcblk0p1
(note that you can clone from a dev kit even if the module is flashed for some other carrier board since it is in recovery mode and won’t care about the existing software in recovery mode)
The above example would create both “my_backup.img
” (sparse) and “my_backup.img.raw
” (raw) and consume many GB of space on the host PC.
You could then loopback mount and work with the raw image something like this:
sudo mount -o loop ./my_backup.img.raw /mnt
# Do things there, e.g., examine:
ls /mnt
# Make sure you did not cd into this location before umount:
sudo umount /mnt
# Now copy it for flash to wherever the flash software is:
cp ./my_backup.img.raw /where/ever/it/is/Linux_for_Tegra/bootloader/system.img.raw
# Create a sparse version (this is optional, the raw image could have been named "system.img" to
# skip this step:
mksparse -v --fillpattern=0 system.img.raw system.img
# Then example command line flash with reusing the image, which is the "-r" part, from "Linux_for_Tegra/":
sudo ./flash.sh -r jetson-xavier-nx-devkit mmcblk0p1
Note again that “jetson-xavier-nx-devkit
” just aliases conf file “jetson-xavier-nx-devkit.conf
”.
I’m not able to help with the multiple simultaneous device flash for production, but the image created and used above would work for that as well.
Btw, the reason why NVIDIA stopped providing a default login account, and instead went with first boot setup, is based laws in California changing this. You might have a reason to set up a default account, but you might also need to figure out how to make sure first boot admin account setup remains. If you’ve created a clone by logging in to a Jetson and setting up software before that clone, then it is possible you would have to reinstall the first boot content. If interested in that, then in “Linux_for_Tegra/rootfs/etc/systemd/system/
”, examine files “nvfb-early.service
”, “nvfb.service
”, and “nv.service
”. Search for “first-boot
” (first boot setup is a systemd
service).