Update DTB on Jetson Nano (Production-EMMC Version)


I’m trying to update the DTB on a Jetson Nano (emmc) without having to reflash the entire image. I have confirmed that the instructions given here work. I created a signed version of the DTB and “dd” it to the correct partition.

I have tried similar things running the current balenaOS but nothing seems to stick (keeps reverting back to original). I’ve tried:

  • dd signed or unsigned dtb to /dev/disk/by-partlabel/DTB
  • Copy new dtb to /boot/ on target/main application
  • Copy new dtb to /boot/ folder on the Host OS

Each time it boots back up but it’s not running the new DTB. Any suggestions?




The balena root file system is read-only at runtime. Can you confirm that you are trying to run the above steps on the balena device when it’s running?

If so, you would have to remount the OS as read-write with mount -o remount,rw /. You can see more details here. Also note that the boot files are in /mnt/boot

Hope this helps

Thanks for the feedback, yes I was running the commands while it was running and I did remount the OS as read-write.

Unfortunately, during my testing I did try the files located in /mnt/boot (specifically the binary files in /mnt/boot/bootfiles) but changing them had no effect. I could write new (signed or unsigned) dtb files to the DTB and RP1 files and it wouldn’t change the resulting device tree that was loaded into the OS.

However, after some poking around I found the correct location. /dev/mmcblk0p13 (partlabel = resin-rootA) is mounted as /mnt/sysroot/active in the HostOS. It appears as though the active device tree is loaded from /mnt/sysroot/active/current/boot/.dtb (I’m using a stock production model so it’s tegra210-p3448-0002-p3449-0000-b00.dtb). The dtb IS NOT signed so it makes life much easier for modifying on the fly (don’t need to use x86/x64 binary tegraflash to sign DTB).

I don’t really understand why it’s working this way but I’m not going to complain, it works. I was able to hog a gpio and it displays the expected behavior. This is much easier to work with than running the native L4T. I Hope this is helpful for others out there.



I might have spoke too soon. Although my method above does work for changing the loaded device tree (in /proc/device-tree) it doesn’t seem to affect some other boot behavior, specifically cameras.

I have replaced all mention of “imx219 1-0010” with “imx219 123-0010” in the device tree:

root@272517e:~# grep "imx219 1-0010" /proc/device-tree/ -rn
root@272517e:~# grep "imx219 123-0010" /proc/device-tree/ -rn
/proc/device-tree/tegra-camera-platform/modules/module0/drivernode0/devname:1:imx219 123-0010

However, when the HostOS boots up and I look at the kernel log, I see imx219 1-0010:

root@272517e:~# dmesg | grep "imx219 1-0010"
[    1.185373] imx219 1-0010: tegracam sensor driver:imx219_v2.0.6
[    1.208827] imx219 1-0010: imx219_board_setup: error during i2c read probe (-121)
[    1.208857] imx219 1-0010: board setup failed

I’ve tried replacing the DTB and RP1 partitions (/dev/disk/by-partlabel/) with a signed DTB but that didn’t work. I also tried using the same signed DTB in /mnt/boot/bootfiles/ but that had no effect.

root@272517e:~# strings /dev/disk/by-partlabel/DTB | grep "imx219 123-0010"
imx219 123-0010
root@272517e:~# strings /mnt/boot/bootfiles/DTB | grep "imx219 123-0010"
imx219 123-0010

So it seems some part of the boot process is using a different device tree. I haven’t seen what other systems exhibit this behavior, so far it’s just the cameras but that’s a pretty significant issue for me.

I would really appreciate comments or feedback from anyone with a better understanding of the boot process and how/where DTBs are loaded.



Hi @smithandrewc , by default u-boot loads the dtb from the rootfs and merges it with the one that was passed by cboot - cboot reads the one in the raw partitions like /dev/disk/…/DTB. So for a test, can you try replace the existing dtb with the one you edited in /mnt/sysroot/active/current/boot/ ? You mention using the eMMC version so I think that would be tegra210-p3448-0002-p3449-0000-b00.dtb

Thanks for the feedback @acostach. I took a signed DTB and wrote it to the /dev/disk/…/DTB and /dev/disk/…/RP1 partitions. That made the necessary changes to get the cameras up. I think my validation checks listed previously were not a good indication if things were working. I haven’t tested yet if the RP1 writing is necessary but when the Nano is flashed I can see it is writing to the RP1 partition and the file written there is identical to the DTB file.

The following worked to modify the DTB for the device without reflashing:

  1. Get working DTB, use tegraflash (or other tools) to sign/encrypt it (now call that file dtb.encrypt). Unfortunately, I believe these tools only run on x86/x64 machines.
  2. Copy dtb and dtb.encrypt to the HostOS or running app.
  3. Mount /dev/disk/by-partlabel/resin-rootA
  4. Overwrite the tegra210…b00.dtb with custom dtb found at //mount-point-for-resin-rootA/current/boot/.
  5. dd if= of=/dev/disk/by-partlabel/DTB
  6. dd if= of=/dev/disk/by-partlabel/RP1
  7. Unmount resin-rootA and reboot.

Thanks for the help.


Hi Andrew

It’s great to hear that it is working now!

Always glad to help - let us know if you need assistance again.

Kind regards

Hi Alida,
Andrew and I have been collaborating a bit on custom DTBs. Thanks again for your help. I think it’s worth considering adding the ability to apply custom DTBs to Jetson Nano boards during the initial flashing process. currently one would have to use the bin/cmd.js -p -m jetson-nano-emmc -f <image>, flash the board, and then:

cp  devicetree.dtb ${workdir}/Linux-for-Tegra/
cd ${workdir}/Linux-for-Tegra/ 
sudo ./flash.sh --no-flash -d devicetree.dtb -k DTB jetson-nano-emmc mmcblk0p1
cp bootloader/devicetree.dtb ../resin/DTB
sudo mount ../resin/resin-rootA /mnt
sudo cp ./devicetree.dtb /mnt/current/boot/t210-[...].dtb
sudo umount /mnt
[reset jetson in forced recovery]
sudo ./flash.sh -c ../resin/flash.xml -k DTB jetson-nano-emmc mmcblk0p12

Mind you I have not succeeded with the above method, but that was likely because the DTB under test had a bug anyway.

However it would be a happy day if I could instead do the following:

cd jetson-flash
cp <path-to>/devicetree.dtb ./
bin/cmd.js -d devicetree.dtb -m jetson-nano-emmc -f <balena-image>


Since, as I’ve been told, the jetson-flash stuff is making its way into Etcher, it would be great if an option like that could sneak in at that point.


Hi Keith,

Applying a custom dtb during flashing implies that it will be overwritten with the default one which comes with the image after a hostOS update. If you want to use a custom dtb you can have it loaded by u-boot, see my post above. If this suits your needs, you can PR your custom dtb in the device repository - example here - and have it shipped with image by default.

1 Like