Flashing a Jetson AGX Xavier while running (not in recovery mode)


Assuming the device doesn’t use the flash storage (perhaps runs from initramfs, or boots to NFS), is it possible to flash it while it’s running? If so, how can it be done?

By flashing, i mean rewriting the rootfs partition (i believe it’s called the APP partition?), and maybe the kernel also.

I’m assuming it’s more complicated than a few dd calls, but is it possible to use the tegraflash.py script for it ?
I’ve tried looking in https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fflashing.html%23, but all the uses cases there are for when in maintenance mode.


Yes, if you are running from something like initramfs or some other root filesystem then you should be able to update the entire system on EMMC.

At D3 we routinely update the kernel and device tree without using recovery mode. This has been very convenient for kernel development. We have a Makefile target named ‘sync’ that updates the Xavier without requiring recovery mode.

This is code from our Makefile.am that may help you. What we do is scp the signed kernel and signed dtb to the Xavier and they use DD to write them to the correct partitions. You should always use the partition labels because the partition numbers can and do change between L4T releases.

There’s a little more to this, I have simplified to make it more readable. We also copy the kernel modules using rsync. Of course this does not address your root filesystem but you could use many different techniques for that including dd or formatting the filesystem and unpacking a tarball.

	"SIGN     $(linux_IMAGE)"
	cd @L4TDIR@/bootloader; \
		./mkbootimg --kernel $(linux_IMAGE) --ramdisk initrd --board mmcblk0p1 --output $(DEPLOY_BUILD_PATH)/boot/boot.img;
	cd $(DEPLOY_BUILD_PATH)/boot; \
		@L4TDIR@/bootloader/tegraflash.py --chip $(FLASH_CHIP_ID) \
		--cmd "sign boot.img" --skipuid > /dev/null;

sync-kernel: sign-kernel
	"SYNC     $(linux_SIGNED_IMAGE)"
	scp $(linux_SIGNED_IMAGE) @TARGET_HOST@:~/boot.img.encrypt > /dev/null
	ssh @TARGET_HOST@ sudo dd bs=10MB if=boot.img.encrypt of=/dev/disk/by-partlabel/kernel > /dev/null 2>&1

$(DEPLOY_BUILD_PATH)/boot/%_sigheader.dtb.encrypt: $(DTB_BUILD_PATH)/%.dtb
	"SIGN      $^"
	cd $(DEPLOY_BUILD_PATH)/boot; \
		@L4TDIR@/bootloader/tegraflash.py --chip $(FLASH_CHIP_ID) \
		--cmd "sign $^" --skipuid;

sign-dtb: $(SIGNED_DTB)

sync-dtb: sign-dtb
	scp $(SIGNED_DTB) @TARGET_HOST@:~/device_tree.dtb.encrypt
	ssh @TARGET_HOST@ sudo dd if=device_tree.dtb.encrypt of=/dev/disk/by-partlabel/kernel-dtb
1 Like

Thanks so much! I will look into that.

@D3_growe BTW what do you use for the initrd (the value for --ramdisk)? Do you provide your own initrd image?

We don’t update the APP partition in-place but, if you are using a ram disk or any root filesystem that isn’t backed by the APP partition itself then techniques like dd or unpacking tar files would work fine.

RidgeRun has done a lot of work supporting Yocto builds on Jetson and have an excellent wiki page.