Getting U-Boot to load dtb from FIT image

13,334

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";
    };
};
Share:
13,334

Related videos on Youtube

ColH
Author by

ColH

Updated on September 18, 2022

Comments

  • ColH
    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
      Tom Rini almost 7 years
      Can you please post the .its file?
    • Tom Rini
      Tom Rini almost 7 years
      Ah, can you also please provide the full environment? Thanks!
    • ColH
      ColH almost 7 years
      Yep, also added above
  • ColH
    ColH almost 7 years
    Ah, thanks - that does indeed work. I had a feeling there ought to be a less convoluted method.