Custom image file for Jetson Nano

I can’t provide any satisfactory answer, but perhaps some information on how the image is created would help.

Normally, when flashing, the content of the “Linux_for_Tegra/rootfs/” (on the host PC) has a purely Ubuntu 18.04 root filesystem unpacked into it. Then some drivers and configuration specific to the Jetson is added (e.g., the GPU driver), and it becomes known as “Linux for Tegra” (“L4T”) at that point. Mostly this is still just Ubuntu.

Then, during flash, and depending on parameters passed (e.g., that it is for a Nano with eMMC versus a Nano dev kit with an SD card), the “rootfs/boot/” content is slightly edited. Those edits are entirely for boot, and perhaps also includes appropriate initrd edits to match.

Then a blank file is created in “Linux_for_Tegra/bootloader/”, the file is loopback formatted to be ext4, and loopback mounted. The content of the “rootfs/” is then recursively copied into the loopback mounted file in a bit-for-bit exact copy.

That file becomes “bootloader/system.img.raw”, and this is an exact copy of the root filesystem. The other partitions are pre-compiled and simply copied as boot content. The “bootloader/system.img.raw” is then turned in to a “sparse” file, which is more or less cheap compression where the empty parts of the filesystem are simply named and not actually copied…this file becomes “bootloader/system.img”, is smaller than system.img.raw, and expands during flash to become the rootfs/APP partition.

If you flash and replace the system.img with the renamed system.img.raw, then flash still works, but takes longer since this file is larger. The raw image though can be loopback mounted, examined, edited, so on, while the sparse image is only good for flashing. There is a utility (“mksparse”, with NULL character as the filler option) to convert any raw image to a sparse image, but doing the reverse of going from sparse to raw is problematic.

Aside from the boot related content in the “rootfs/”, e.g, the extlinux.conf file, perhaps the kernel image and initrd, everything there is copied verbatim. This means that:

  • If you clone a Jetson’s rootfs partition, and mount this on the “rootfs/”, then other than the boot edits this will be an exact copy of your clone;
  • If you use manual flash and tell it to reuse the system.img, but the system.img is your clone of rootfs, then that image will be a 100% exact match on the destination Jetson without any edits.

Earlier I mentioned that the “rootfs/” content is slightly edited. In the case where those edits are via packages the QEMU emulator is used to directly run dpkg commands inside the “rootfs/”. To see how that goes you might examine how the “apply_binaries.sh” script works (this is what runs QEMU and applies the NVIDIA-specific files). You could modify this and use QEMU to remove packages or add your own custom packages prior to flash. Or you could make those edits on a Jetson, and clone the Jetson, then use the clone for flash.

It is actually intended that the end user might modify this content in the “rootfs/”, and is why it is called a “sample” rootfs.

The part which probably shouldn’t be modified is the surrounding boot-related content. All of those other partitions beyond the rootfs are used in boot. Some partitions are equivalent to what a PC’s motherboard would call the CMOS BIOS, other parts are just bootloader content. Since the Jetson doesn’t have a BIOS you see all of that content as partitions. The use and layout of this changes depending on whether this is an eMMC model or an SD card model.

Of all of the content within the sample rootfs much can be changed. However, you would want to be certain that the Xorg X server uses the same ABI. The GPU driver plugs into the Xorg X server, and if the ABI changes, then you lose direct hardware accelerated drivers. Other than that and the boot chain you are pretty much free to change anything.

If you learn to use QEMU in the same way which “apply_binaries.sh” does, then you are probably free to experiment directly on your PC with adding and removing packages, or even entire Ubuntu 18.04 variants. Or if you make such changes directly on a Jetson and you then clone it…either way.