Device tree modification problems in 28.1

I’m trying to make just two small gpio changes to the stock dev board device tree. I’ve tried the following things:

  1. First I tried decompile the dtb file tegra186-quill-p3310-1000-c03-00-base.dtb and then I made my changes to the .dtc and then recompiled and put it on the the TX2 filesystem. Then I added the FDT entry to /boot/extlinux/extlinux.conf file. My gpio changes worked but I no longer had an ethernet interface available. I also tried just using the unmodified .dtb file but it also had no ethernet.

  2. So then I looked in jetson-tx2.conf in linux4tegra 28.1 package and saw that it was configured to use tegra186-a02-bpmp-quill-p3310-1000-a00-00-te770d-ucm2.dtb so I tried decompiling that and making my changes but when I booted using that dtb the tegra halts and fails to boot. I also tried booting with the tegra186-a02-bpmp-quill-p3310-1000-a00-00-te770d-ucm2.dtb unmodified but same result.

So what am I supposed to do? How can I extract the actual dtb file from the working image on the TX2? Why does it seem like there is a mismatch between the dtb that is already built into the image and the ones you provide in the source?

Thank you for your response.

“/proc/device-tree” is a reflection of the running kernel’s tree. This will convert it to an editable source file (not sure if sudo is required, it won’t hurt though):

sudo dtc -I fs -O dts -o extracted.dts /proc/device-tree

Thanks linuxdev! I’ll give that a try.

Something I found odd was that I did a diff of the /proc/device-tree folders on the TX2 when running the stock device tree and when running the tegra186-quill-p3310-1000-c03-00-base.dtb (using FDT) and there were no differences! Yet ethernet worked on stock and not on the the dtb loaded using FDT. Is there some different behavior when loading a a dtb with FDT?

Just speculating, but all I can think of is a timing difference based on when devices are set up between initial boot and kernel load. You know the final booted result has the same tree, so anything occurring after kernel load should be equal…but you don’t know what went on in which order of setup prior to initial kernel load. It would be interesting to know the answer to this.

I ended up making a new DTS using the dtc command you provided above, then I added my modifications and put it back on the TX2 and added the FDT command to extlinux.conf and now ethernet works. The problem I now have is that one of my pins are getting driven high during during uBoot and then once the kernel loads it sets to an input (and pulls low from my pulldown resistor) as specified by my DTB.

So is uBoot ignoring the FDT command and using a different DTB?

U-Boot has its own device tree in its environment. The kernel load occurs as U-Boot’s life is ending, and after the dtb file you provided is loaded between the life of U-Boot and the beginning of the kernel…in theory if you used “/proc/device-tree” this would be the same as setting the hardware state to the state it is already in, but I can’t swear that loading a register with the value which was already in it won’t have an effect (e.g., the register will match the old register, but perhaps the hardware takes an action if the register has been written to without caring that the value is the same as it used to be…I don’t know). One thing you can be sure of is that even if the device tree is constant, the drivers interfacing to the tree will change. U-Boot has its drivers, the Linux kernel has its own. Whether or not there is a continuity of operation on transfer from one driver to the other just depends.

Thanks linuxdev,
From what I’ve read though, uBoot should be pulling the same DTB as the kernel as specified by my FDT command. If this is not true, how do I change the DTB that uBoot uses?

Or maybe I misunderstood, are you saying that uBoot’s “interpretation” of the DTB might be different (due to driver differences) and that is the reason why my pinmux change is working in the kernel but not in uBoot? In this case, I’m pretty doubtful that’s the problem since I’m only modifying two pins directions, but who knows.

There are some serial console command line options for displaying device tree, but I have not used them. It would require research to find out how to see the loaded device tree from U-Boot…it is different to display a device tree file versus displaying the current device tree configuration since you don’t know if the file is what loaded that configuration, and you don’t know if there were rejected or altered components (some registers could be modified by the driver itself).

You are correct that getting the “/proc/device-tree” should (more or less) be an exact copy, but timing of when the device tree is loaded, in combination with what drivers do, may change things. Hardware state inherited at the point of loading a particular DTB can be inherited, and is not necessarily caused by the device tree itself (an example of this showing up is that a warm boot may have a difference from a cold boot even if the two are supposed to initialize to the same state). When you mention “uBoot should be pulling the same DTB as the kernel as specified by my FDT command”, can you give the exact details of which FDT file you are using? Was it generated from the “/proc/device-tree”?

The base U-Boot image is flashed via this:

sudo ./flash -r -K LNX jetson-tx1 mmcblk0p1

…which implies it can be cloned via partition “LNX”.

Roughly speaking, it seems flashing just the DTB on a JTX2 under R28.1 would be:

sudo ./flash -k -r kernel-dtbjetson-tx2 mmcblk0p1

Although I have not tried it, it seems likely you could clone anything which can be named for flash. The question is naming the partition you want to clone. If you can do this, then you could generate a DTS file from the cloned device tree partition which U-Boot loads, and then compare that.

I am not sure how to clone the U-Boot device tree though, since it is not a partition in the usual sens. Note that “-K” implies a partition, but “-k” implies a kernel. I can find no reference to “-r kernel-dtbjetson-tx2” in any of the flash software, so I don’t know exactly what this does.

Can someone at NVIDIA provide a way to clone the device tree which is on an R28.1 JTX2 which would exist as a result of the “-r kernel-dtbjetson-tx2” flash? And what file is used for device tree using this? Is this a subset of one of the partitions, e.g., is this padded somewhere into the U-Boot binary partition?

So far it looks like the FDT command in extlinux.conf file is broken or no longer works in 28.1 to change the device tree. I am also having all sorts of issues with this…

I ended up just changing the pinmux cfg file and rebuilding/flashing the uboot and kernel and everything works fine. So whatever, I guess I have a solution. But I can only conclude that using the FDT command on specifies the DTB that the kernel will use and does not affect uBoot. It would be nice to know if there is a way to specify a new DTB for both

The device tree named in the FDT entry of extlinux.conf has never had any effect during the life of U-Boot. Basically U-Boot only loads the FDT and kernel image right before branching to the kernel (which essentially ends the life of U-Boot by overwriting itself). Flashing a DTB into some partition where U-Boot searches for its own FDT allows U-Boot to take advantage of this…and if hardware state is preserved when branching to the kernel this DTB becomes active. You can still use the FDT entry for operations which only need to work after the kernel takes over.

I see, thanks for clearing that up