Getting U-Boot to load dtb from FIT image
Solution 1
The answer to this exact problem comes from understanding that U-Boot tries to be extremely flexible and this can lead to some confusion at times. Looking at the provided environment we can see that we have the bootcmd (which is executed when the boot delay runs out) boils down to:
bootm ${loadaddr} - ${fdtaddr}
And this means that we look at ${loadaddr} for our image, no where for a ramdisk and ${fdtaddr} for the device tree to use. In the case of a legacy-style uImage this makes sense as the ramdisk and device tree are not (likely) to be contained within the file. A FIT image however has all of this included, and offers lots of extra useful features (which the poster wishes to use). What happens is that after picking out the device tree included in the FIT image, U-Boot then parses the rest of the arguments and looks at ${fdtaddr} for the device tree to use. If bootm_cmd was set to simply:
bootm ${loadaddr}
instead, it would work as expected.
Solution 2
add load in fdt node
fdt@1 {
description = "Flattened Device Tree blob";
data = /incbin/("arch/arm/boot/dts/tx6.dtb");
type = "flat_dt";
arch = "arm";
load = <0x18000000>
compression = "none";
hash@1 {
algo = "sha1";
};
};
Related videos on Youtube
ColH
Updated on September 18, 2022Comments
-
ColH almost 2 years
I'm working towards setting up U-Boot to boot only verified Linux kernel from a Kernel+fdt FIT image. (Everything is built under Yocto). The U-Boot bin has a basic device tree appended to it which it boots up using, but the FIT image has the full tree for the kernel.
I have everything pretty much working, except that when the kernel is booted, U-Boot is ignoring the device tree in the FIT image and instead passing its own one - based on the value of fdtaddr (== 0x11000000):
Hit any key to stop autoboot: 0 reading uImage 3346230 bytes read in 100 ms (31.9 MiB/s) ## Loading kernel from FIT Image at 18000000 ... No configuration specified, trying default... Found default configuration: 'conf@1' Using 'conf@1' configuration Verifying Hash Integrity ... sha1,rsa2048:dev+ OK Trying 'kernel@1' kernel subimage Description: Linux kernel Type: Kernel Image Compression: uncompressed Data Start: 0x180000e8 Data Size: 3304016 Bytes = 3.2 MiB Architecture: ARM OS: Linux Load Address: 0x10008000 Entry Point: 0x10008000 Hash node: 'hash@1' Hash algo: sha1 Hash value: ff0333f01a894f81d716605f7c7995d651ff8111 Hash len: 20 Verifying Hash Integrity ... sha1+ OK * fdt: cmdline image address = 0x11000000 ## Checking for 'FDT'/'FDT Image' at 11000000 Wrong FIT format: no description * fdt: raw FDT blob ## Flattened Device Tree blob at 11000000 Booting using the fdt blob at 0x11000000 of_flat_tree at 0x11000000 size 0x0000505a Loading Kernel Image ... OK ## device tree at 11000000 ... 11005059 (len=32858 [0x805A]) Loading Device Tree to 2f72e000, end 2f736059 ... OK
[NB my U-Boot has some board-specific modules - from the board manufacturer - which might be altering U-Boot's standard behaviour]
I can get correct operation, if after the image is loaded, I "setenv fdtaddr ${loadaddr}" (== 0x18000000) - then U-Boot does find the device tree in the FIT image and passes that instead:
Hit any key to stop autoboot: 0 reading uImage 3346230 bytes read in 101 ms (31.6 MiB/s) ## Loading kernel from FIT Image at 18000000 ... No configuration specified, trying default... Found default configuration: 'conf@1' Using 'conf@1' configuration Verifying Hash Integrity ... sha1,rsa2048:dev+ OK Trying 'kernel@1' kernel subimage Description: Linux kernel Type: Kernel Image Compression: uncompressed Data Start: 0x180000e8 Data Size: 3304016 Bytes = 3.2 MiB Architecture: ARM OS: Linux Load Address: 0x10008000 Entry Point: 0x10008000 Hash node: 'hash@1' Hash algo: sha1 Hash value: ff0333f01a894f81d716605f7c7995d651ff8111 Hash len: 20 Verifying Hash Integrity ... sha1+ OK * fdt: cmdline image address = 0x18000000 ## Checking for 'FDT'/'FDT Image' at 18000000 ## Loading fdt from FIT Image at 18000000 ... No configuration specified, trying default... Found default configuration: 'conf@1' Using 'conf@1' configuration Trying 'fdt@1' fdt subimage Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Start: 0x18326c2c Data Size: 38269 Bytes = 37.4 KiB Architecture: ARM Hash node: 'hash@1' Hash algo: sha1 Hash value: 79d5eeb892ef059566c04d98cdc6b30e92a665a2 Hash len: 20 Verifying Hash Integrity ... sha1+ OK Can't get 'load' property from FIT 0x18000000, node: offset 3304372, name fdt@1 (FDT_ERR_NOTFOUND) Booting using the fdt blob at 0x18326c2c of_flat_tree at 0x18326c2c size 0x0000957d Loading Kernel Image ... OK ## device tree at 18326c2c ... 183301a8 (len=50557 [0xC57D]) Loading Device Tree to 2f72a000, end 2f73657c ... OK
This is fine (I can add the above command to 'default_bootargs'), but I wondered if I'm missing some 'proper' trick to get the same behaviour - I kinda assumed that if you loaded a FIT image then U-Boot would naturally load not only the kernel from it but also the device tree. (I've not yet been able to grasp the options on the bootm command...)
Thanks
[Edit:]
/dts-v1/; / { description = "U-Boot fitImage for MyBoard/4.4/tx6"; #address-cells = <1>; images { kernel@1 { description = "Linux kernel"; data = /incbin/("linux.bin"); type = "kernel"; arch = "arm"; os = "linux"; compression = "none"; load = <0x10008000>; entry = <0x10008000>; hash@1 { algo = "sha1"; }; }; fdt@1 { description = "Flattened Device Tree blob"; data = /incbin/("arch/arm/boot/dts/tx6.dtb"); type = "flat_dt"; arch = "arm"; compression = "none"; hash@1 { algo = "sha1"; }; }; }; configurations { default = "conf@1"; conf@1 { description = "Linux kernel, FDT blob"; kernel = "kernel@1"; fdt = "fdt@1"; hash@1 { algo = "sha1"; }; signature@1 { algo = "sha1,rsa2048"; key-name-hint = "dev-example"; sign-images = "kernel", "fdt"; }; }; }; };
[Edit:]
autoload=no autostart=no baseboard=stk5-v3 baudrate=115200 boot_mode=mmc bootargs_jffs2=run default_bootargs;setenv bootargs ${bootargs} root=/dev/mtdblock3 rootfstype=jffs2 bootargs_mmc=run default_bootargs;setenv bootargs ${bootargs} root=PARTUUID=${rootpart_uuid} rootwait bootargs_nfs=run default_bootargs;setenv bootargs ${bootargs} root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock ip=dhcp bootargs_sdcard=run default_bootargs;setenv bootargs ${bootargs} root=/dev/mmcblk0p2 rootwait bootargs_ubifs=run default_bootargs;setenv bootargs ${bootargs} ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs bootcmd=run bootcmd_${boot_mode} bootm_cmd bootcmd_jffs2=setenv autostart no;run bootargs_jffs2;nboot linux bootcmd_mmc=setenv autostart no;run bootargs_mmc;fatload mmc 0 ${loadaddr} ${bootfile} bootcmd_net=setenv autoload y;setenv autostart n;run bootargs_nfs;dhcp bootcmd_sdcard=setenv autostart no;run bootargs_sdcard;fatload mmc 1:1 ${loadaddr} ${bootfile} bootdelay=1 bootfile=uImage bootm_cmd=bootm ${loadaddr} - ${fdtaddr} cpu_clk=792 default_bootargs=setenv bootargs init=/sbin/init console=ttymxc0,115200 ro debug panic=1 ${append_bootargs}; setenv fdtaddr ${loadaddr} emmc_boot_ack=1 emmc_boot_part=1 ethact=FEC ethaddr=00:01:02:7f:e5:50 fdtaddr=11000000 fdtsave=mmc partconf 0 ${emmc_boot_ack} ${emmc_boot_part} ${emmc_boot_part};mmc write ${fdtaddr} 0x680 80;mmc partconf 0 ${emmc_boot_ack} ${emmc_boot_part} 0 fdtsize=505a loadaddr=18000000 nfsroot=/tftpboot/rootfs otg_mode=device rootpart_uuid=0cc66cc0-02 splashimage=18000000 stderr=serial stdin=serial stdout=serial touchpanel=edt-ft5x06 ver=U-Boot 2015.10-rc2 (Aug 11 2017 - 18:57:06 +0100) video_mode=VGA
-
Tom Rini almost 7 yearsCan you please post the .its file?
-
Tom Rini almost 7 yearsAh, can you also please provide the full environment? Thanks!
-
ColH almost 7 yearsYep, also added above
-
-
ColH almost 7 yearsAh, thanks - that does indeed work. I had a feeling there ought to be a less convoluted method.