我正在努力设置 U-Boot 以仅从 Kernel+fdt FIT 映像启动经过验证的 Linux 内核。 (一切都是在 Yocto 下构建的)。 U-Boot bin 附加了一个用于启动的基本设备树,但 FIT 映像具有内核的完整树。
我已经一切正常,除了当内核启动时,U-Boot 忽略 FIT 映像中的设备树,而是根据 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
[注意,我的 U-Boot 有一些特定于板的模块 - 来自板制造商 - 这可能会改变 U-Boot 的标准行为]
如果加载图像后,我可以得到正确的操作,我“setenv fdtaddr ${loadaddr}”(== 0x18000000) - 然后U-Boot做在 FIT 映像中找到设备树并传递它:
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
这很好(我可以将上面的命令添加到“default_bootargs”),但我想知道我是否缺少一些“适当的”技巧来获得相同的行为 - 我有点假设如果你加载了一个 FIT 图像,那么 U-Boot 会自然地,不仅会从中加载内核,还会加载设备树。 (我还无法掌握 bootm 命令的选项......)
谢谢
[编辑:]
/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";
};
};
};
};
[编辑:]
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
答案1
这个确切问题的答案来自于对 U-Boot 试图变得极其灵活的理解,这有时会导致一些混乱。查看提供的环境,我们可以看到 bootcmd(在启动延迟结束时执行)可归结为:
bootm ${loadaddr} - ${fdtaddr}
这意味着我们看${加载地址}为了我们的形象,无处可去对于 ramdisk 和${fdtaddr}供设备树使用。对于传统风格的 uImage 来说,这是有意义的,因为 ramdisk 和设备树(可能)不包含在文件中。然而,FIT 图像包含所有这些内容,并提供许多额外有用的功能(发布者希望使用的功能)。发生的情况是,在挑选出 FIT 映像中包含的设备树后,U-Boot 会解析其余参数并查找 ${fdtaddr} 来使用设备树。如果启动命令设置为简单:
bootm ${loadaddr}
相反,它会按预期工作。
答案2
在fdt节点中添加负载
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";
};
};