u-boot error when loading custom device tree from /boot with extlinux.conf

Hi,
I’m trying to boot linux-stable on Jetson TX2. I’ve specified an alternative boot entry in extlinux.conf which uses tegra186 DT from:

$ cat Linux_for_Tegra/rootfs/boot/extlinux/extlinux.conf
TIMEOUT 30
DEFAULT dev

MENU TITLE p2771-0000 eMMC boot options

LABEL dev
      MENU LABEL dev kernel
      LINUX /boot/Image-dev
      FDT /boot/tegra186-p2771-0000.dtb
      APPEND ${cbootargs} root=/dev/mmcblk2p1 rw rootwait rootfstype=ext4

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

However I see the following error from u-boot when booting “dev”:

Retrieving file: /boot/tegra186-p2771-0000.dtb
23528 bytes read in 170 ms (134.8 KiB/s)
## Flattened Device Tree blob at 82200000
   Booting using the fdt blob at 0x82200000
   Using Device Tree in place at 0000000082200000, end 0000000082208be7
WARNING: could not set reg FDT_ERR_NOSPACE.
ERROR: arch-specific fdt fixup failed
 - must RESET the board to recover.

FDT creation failed! hanging...### ERROR ### Please RESET the board ###

I think the FDT_ERR_NOSPACE warning is u-boot complaining about not having enough room for the DT however linux-stable DT is about 10x smaller than the the linux-tegra DT:

-rw-r--r-- 1 tpreston tpreston  23528 Jun 11 14:31 dtb/linux-stable/tegra186-p2771-0000.dtb
-rw-r--r-- 1 tpreston tpreston 279148 Jun  7 16:44 Linux_for_Tegra/kernel/dtb/tegra186-quill-p3310-1000-c03-00-base.dtb

Is it possible to load custom DT’s like this? Or do I have to flash with:

./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1

See:
https://devtalk.nvidia.com/default/topic/1036286/jetson-tx1/flashing-just-dtb-on-28-2-and-tx1/post/5264465/#5264465

Do note that during normal flash extlinux.conf in “rootfs/boot/extlinux/” may get overwritten depending on arguments from the flash. On the other hand, if you “reuse” the system.img (the “-r” option), then this won’t occur, but you’ll be using whatever system.img is in place.

If system.img is the normal “sparse” image, then you cannot edit it. However, you can loopback mount and edit “system.img.raw”. After that you can either copy it to name “system.img” (flash will take much longer, it isn’t compressed/sparse), or create a new sparse image from the raw image (mksparse and system.img and system.img.raw are in the “bootloader/” subdirectory):

# It's just a NULL byte fill pattern:
sudo mksparse -v --fillpattern=0 system.img.raw system.img

Hi, thanks for the response.

I edit the following file, which overwrites extlinux.conf during the flash:

$ vim Linux_for_Tegra/bootloader/t186ref/p2771-0000/extlinux.conf.emmc
$ ./flash.sh jetson-tx2 mmcblk0p1

And the following flash.sh command seems to write the DTB partition just fine for me

./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1

Which I can confirm with (linux-stable has internal mmc at /dev/mmcblk2 for some reason):

root@tegra-ubuntu:~# cat /proc/device-tree/model
NVIDIA Tegra186 P2771-0000 Development Board
root@tegra-ubuntu:~# strings /dev/mmcblk2p26 | grep "NVIDIA Tegra186 P2771-0000 Development Board"
7NVIDIA Tegra186 P2771-0000 Development Board

My question was about loading a different device-tree at the u-boot stage. This is because I’m trying to boot a newer kernel (linux-stable v4.16.14) which has different device tree requirements than linux-tegra (BSP r28.2)

I’m happy for cboot to use whatever device tree it requires from the internal mmc, but I was hoping I could swap it out just before Linux is loaded. In the other thread you said that the DT must be signed - is this also true for linux/u-boot? Do you know how this works?

https://devtalk.nvidia.com/default/topic/1036380/jetson-tx2/jetson-tx2-flash-only-kernel-image/post/5265205/#5265205

The flash tool places a signature at the start of the device tree in the partition containing that tree. I do not know the details of how the signing is done, but using the flash.sh tool does provide signing. The other URL mentions a bug needing edit in order to prevent overwriting the rootfs as well (the “reuse” option, for this case, should not flash rootfs at all…but apparently without the fix it does…again, not sure of details).

This command (assuming you’ve patched) should flash just the device tree partition (the example is pointing to a specific dtb which is flashed by default, but it could be any unsigned dtb file):

sudo ./flash.sh -r -d ./kernel/dtb/tegra186-quill-p3310-1000-c03-00-base.dtb jetson-tx2 mmcblk0p1

If using the default dtb (the dtb from the previous example) then this would probably be the same thing, but I won’t guarantee it:

sudo ./flash.sh -r -k kernel-dtb jetson-tx2 mmcblk0p1

Clone anything important before you test device tree changes.

That’s interesting about loading arbitrary device trees with the flash.sh tool, thanks.

I’m still trying to load a device tree from u-boot using:

U-Boot 2016.07-g9c3b9a4 (Mar 01 2018 - 20:41:10 -0800)

TEGRA186
Model: NVIDIA P2771-0000-500
DRAM:  7.8 GiB
MC:   Tegra SD/MMC: 0, Tegra SD/MMC: 1
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@2490000
Hit any key to stop autoboot:  0 

Tegra186 (P2771-0000-500) # printenv fdt_addr
fdt_addr=92000000

Tegra186 (P2771-0000-500) # md 92000000
92000000: edfe0dd0 e07b0000 38000000 ec5b0000    ......{....8..[.
92000010: 28000000 11000000 10000000 00000000    ...(............
92000020: 36080000 b45b0000 00000000 00000000    ...6..[.........
92000030: 00000000 00000000 01000000 00000000    ................
92000040: 03000000 0e000000 28080000 31323430    ...........(0421
92000050: 30383131 35383433 30300036 03000000    118034856.00....
92000060: 22000000 00000000 6469766e 702c6169    ..."....nvidia,p
92000070: 31373732 3030302d 766e0030 61696469    2771-0000.nvidia
92000080: 6765742c 38316172 00000036 03000000    ,tegra186.......
92000090: 04000000 0b000000 01000000 03000000    ................
920000a0: 04000000 1c000000 02000000 03000000    ................
920000b0: 04000000 2b000000 02000000 03000000    .......+........
920000c0: 2d000000 37000000 4449564e 54204149    ...-...7NVIDIA T
920000d0: 61726765 20363831 37373250 30302d31    egra186 P2771-00
920000e0: 44203030 6c657665 656d706f 4220746e    00 Development B
920000f0: 6472616f 00000000 01000000 65736572    oard........rese

Tegra186 (P2771-0000-500) # load mmc 0 92000000 /boot/tegra186-p2771-0000.dtb
23528 bytes read in 170 ms (134.8 KiB/s)

Tegra186 (P2771-0000-500) # md 92000000                                      
92000000: edfe0dd0 e85b0000 38000000 9c550000    ......[....8..U.
92000010: 28000000 11000000 10000000 00000000    ...(............
92000020: 4c060000 64550000 00000000 00000000    ...L..Ud........
92000030: 00000000 00000000 01000000 00000000    ................
92000040: 03000000 22000000 00000000 6469766e    ......."....nvid
92000050: 702c6169 31373732 3030302d 766e0030    ia,p2771-0000.nv
92000060: 61696469 6765742c 38316172 00000036    idia,tegra186...
92000070: 03000000 04000000 0b000000 01000000    ................
92000080: 03000000 04000000 1c000000 02000000    ................
92000090: 03000000 04000000 2b000000 02000000    ...........+....
920000a0: 03000000 2d000000 37000000 4449564e    .......-...7NVID
920000b0: 54204149 61726765 20363831 37373250    IA Tegra186 P277
920000c0: 30302d31 44203030 6c657665 656d706f    1-0000 Developme
920000d0: 4220746e 6472616f 00000000 01000000    nt Board........
920000e0: 6373696d 30303140 00303030 03000000    misc@100000.....
920000f0: 15000000 00000000 6469766e 742c6169    ........nvidia,t

Tegra186 (P2771-0000-500) # boot
MMC: no card present
switch to partitions #0, OK
mmc0(part 0) is current device
Scanning mmc 0:1...
Found /boot/extlinux/extlinux.conf
Retrieving file: /boot/extlinux/extlinux.conf
399 bytes read in 139 ms (2 KiB/s)
p2771-0000 eMMC boot options
1:      dev kernel
2:      linux-tegra kernel
Enter choice: 1
1:      dev kernel
Retrieving file: /boot/Image-dev
17517056 bytes read in 567 ms (29.5 MiB/s)
append: root=/dev/mmcblk0p1 rw rootwait console=ttyS0,115200n8 ignore_loglevel earlyprintk OS=l4t fbcon=map:0 net.ifnames=0 memtype=0 vi
deo=tegrafb no_console_suspend=1 earlycon=uart8250,mmio32,0x03100000 nvdumper_reserved=0x2772e0000 gpt tegraid=18.1.2.0.0 tegra_keep_boo
t_clocks maxcpus=6 boot.slot_suffix= boot.ratchetvalues=0.2.1 androidboot.serialno=0421118034856 bl_prof_dataptr=0x10000@0x277040000 sdh
ci_tegra.en_boot_part_access=1 root=/dev/mmcblk2p1 rw rootwait rootfstype=ext4
## Flattened Device Tree blob at 92000000
   Booting using the fdt blob at 0x92000000
   Using Device Tree in place at 0000000092000000, end 0000000092008be7
WARNING: could not set reg FDT_ERR_NOSPACE.
ERROR: arch-specific fdt fixup failed
 - must RESET the board to recover.

FDT creation failed! hanging...### ERROR ### Please RESET the board ###

I’m not sure if this is because of the signature or some other reason.

I’ve never succeeded in loading a device tree from U-Boot. The signature would be an issue as well if using R28.2 (R28.1 did not use the signature). There are some questions out on how to accomplish signing with open source tools, but at the moment I have not seen a way to do this. Once that is done you might be able to load from U-Boot, but keep in mind that there are several boot stages prior to U-Boot which seem to merge into this (I don’t know the details, but the final device tree as seen by the Linux kernel might be a slightly edited version of whatever you provide).

Okay so the error is because u-boot is trying to make changes to the FDT reg nodes (a bug fixed in upstream u-boot I think), but it can’t because the DT I’ve built is limited in size. Hence the error after the fdt_setprop() call in common/fdt_support.c:454:

WARNING: could not set reg FDT_ERR_NOSPACE

The flash.sh tool ensures that the DT written to /dev/mmcblk0p26 is always 524288 B - which has room to grow.

I made the following change to the NVIDIA dts Makefile and now I can load this kernel+DT with u-boot using the Linux_for_Tegra/rootfs/boot/extlinux/extlinux.conf in my OP:

diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index 676aa2f238d1..cb330d005a40 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -5,3 +5,4 @@ dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb
 dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb
+DTC_FLAGS ?= -a 524288

That makes sense. FYI, any of the binary images which are smaller than the partition used are normally padded with NULL bytes at the end. I suspect that only one NULL byte pad is required though at the end of a device tree used in a device tree partition.

Thanks for sharing the fix Thomas, however, unfortunately I’ve noticed, at least in my case (on TX2 32.1), that USB doesn’t work when loading the FDT from extlinux. So there must be some requirement to load from the fixed partitions in the partition table/and or something loading in cboot. I think the solution to this will be to use Bootloader Update and Redundancy outlined at https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fbootloader_update.html%23 instead. See related post at https://github.com/madisongh/meta-tegra/issues/178

It has been quite some time since extlinux.conf’s FDT entry has been used. At some point it became necessary for boot stages prior to the bootloader to have access to this, and those stages are unable to read ext4 filesystems. The content migrated to a partition, and additionally started requiring signing in support of some secure boot features. Those earlier stages may slightly edit the tree, and then the bootloader inherits that tree. See the documents on customization and documents on flashing device trees (the instructions may vary slightly across different releases).