Select a device tree on boot

Hi, I have a situation where there are two physical machines with nano devices inside. They have different hardware configurations. The rest of the kernel/software is identical. I wish to do one build which will be loadable onto either device.

I’m not sure how the device tree is selected on boot, is there any information on how this decision is made? I can see from the boot log where the tree is found - is there any detail on how the tree is found?

## Flattened Device Tree blob at 83100000
   Booting using the fdt blob at 0x83100000
ERROR: reserving fdt memory region failed (addr=0 size=0)
ERROR: reserving fdt memory region failed (addr=0 size=0)
   Using Device Tree in place at 0000000083100000, end 000000008317b7f1
copying carveout for /host1x@50000000/dc@54200000...
copying carveout for /host1x@50000000/dc@54240000...

The device hardware can be recognised via hardware interrogation within u-boot and I’d like to decide which device tree to use, load in the DT then boot as normal. I’m using the standard tegraflash recipe for the image and I’m flashing via the USB. Is there a recommended way to do this or does anyone have suggestions?

Is this Nano a dev kit from NVIDIA? Or does it use a third party carrier board? Dev kits have the SD card slot on the module itself, whereas third party carrier boards have any SD card slot on the carrier board (and eMMC for the module).

Do you have a serial console available at boot? If so, then just create a second boot entry which is a copy of the original, but which edits which tree is loaded.

eMMC has some different options, but if this is a dev kit SD card model, then I’d expect “/boot/extlinux/extlinux.conf” to have an “FDT” key/value pair pointing where to find the device tree. If a second boot entry is present which differs only in the “FDT” entry (keep in mind they must have different labels too), then you could simply pick which to boot to via serial console.

This is a 3rd party board developed initially with the jetson-nano-devkit. Yes I have serial a console available.

When you say ‘create a second boot entry’ what is the process for doing this and how does the selection work?

The 3rd party board uses eMMC.

First I’ll mention some of the device tree loading options.

On an eMMC model, there is a device tree partition. That gets a signed copy of the dtb file. There is also the “FDT” key/value entry in “extlinux.conf”. That extlinux.conf entry takes precedence in most cases, so adding something there determines which device tree loads, and you can make multiple boot entries. The exception is that on an eMMC model the security fuses can be burned, and if they are, then only the signed partition is accepted (burned security keys will cause the FDT entry to be ignored).

Note that I said “signed” partition for the case when loading via partition. If a .dtb file were directly placed in that partition without signing, then it would be rejected. The file named in the FDT entry does not have that limitation.

Any time someone installs a new kernel or a new device tree I usually suggest they test first with an alternate boot entry (which is accessible via a key to interrupt boot at the proper time during boot over the serial console). One would be offered a chance to pick the boot entry, otherwise it would use the default entry.

An example boot entry is something like this (although this is from a TX2):

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

Note that in that example there is no FDT entry, and so it uses the signed partition. Here’s an edited file which always uses the file; I’ll name the stock/unmodified dtb file “original.dtb” (use your imagination, its whatever is currently used), and I’ll name the other “original-modified.dtb” (which I use that convention because I like to name the modified file after the original file of origin, but it’s just a modification of name to let you know what it is):

LABEL primary
      MENU LABEL primary kernel
      FDT /boot/dtb/original.dtb
      LINUX /boot/Image
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

LABEL modified
      MENU LABEL modified device tree
      FDT /boot/dtb/original-modified.dtb
      LINUX /boot/Image
      APPEND ${cbootargs} root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4

If you interrupt boot too early (it is a rather narrow moment when you can interrupt; the first interrupt is to the boot console, the second is to select kernel), then you can continue with the command:
boot

If you interrupt during that short time when you can select kernel, and if you have multiple kernel entries (as in the example), then you will see a numbered choice of kernels. The “MENU LABEL” will be visible next to the numeric list. For the example above, it might look like:

1. primary kernel
2. modified device tree

You’d hit the backspace to get rid of the key you typed to drop into the kernel select stage, and then hit the “2” key to pick the modified device tree.

You can verify which device tree via serial console log since it shows this in stages prior to Linux ever loading. You can also look for content which is in one dtb but not the other via examining “/proc/device-tree” (this is the kernel showing what it thinks the device tree was at load time).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.