Linux:使用U-Boot和Flat Image Tree(FIT)启动参数

Los*_*Boy 6 arguments linux-kernel u-boot device-tree

我正在尝试使用自己的U-Boot构建来在Jetson TK1板上启动Linux.当我们推动验证启动时,我使用平面图像树(统一内核映像,设备树blob,...)来描述我的系统.U-Boot可以加载ITB文件并尝试启动内核,但系统会在此消息后挂起.

我假设这是因为没有引导参数传递给内核(原始启动添加了参数的加载)但我对如何将参数传递给内核有点傻眼.我尝试设置bootargs环境变量,但这并没有改变这种情况.

使用ITB文件时如何将内核参数传递给内核?

命令行参数(取自示例extlinux.conf的APPEND命令):

console=ttyS0,115200n8 console=tty1 no_console_suspend=1 
lp0_vec=2064@0xf46ff000 video=tegrafb mem=1862M@2048M memtype=255 ddr_die=2048M@2048M 
section=256M pmuboard=0x0177:0x0000:0x02:0x43:0x00 vpr=151M@3945M tsec=32M@3913M 
otf_key=c75e5bb91eb3bd947560357b64422f85 usbcore.old_scheme_first=1 core_edp_mv=1150 
core_edp_ma=4000 tegraid=40.1.1.0.0 debug_uartport=lsport,3 power_supply=Adapter 
audio_codec=rt5640 modem_id=0 android.kerneltype=normal usb_port_owner_info=0 
fbcon=map:1 commchip_id=0 usb_port_owner_info=0 lane_owner_info=6 emc_max_dvfs=0 
touch_id=0@0 tegra_fbmem=32899072@0xad012000 board_info=0x0177:0x0000:0x02:0x43:0x00 
root=/dev/mmcblk0p1 rw rootwait tegraboot=sdmmc gpt
Run Code Online (Sandbox Code Playgroud)

ITS文件的内容:

/dts-v1/;

/ {
    description = "Simple image with single Linux kernel and FDT blob";
    #address-cells = <1>;

    images {
        kernel@1 {
            description = "Vanilla Linux kernel";
            data = /incbin/("./zImage");
            type = "kernel";
            arch = "arm";
            os = "linux";
            compression = "none";
            load = <0x81008000>;
            entry = <0x81008000>;
            hash@1 {
                algo = "crc32";
            };
            hash@2 {
                algo = "sha1";
            };
        };
        fdt@1 {
            description = "Flattened Device Tree blob";
            data = /incbin/("./tegra124-pm375.dtb");
            type = "flat_dt";
            arch = "arm";
            compression = "none";
            hash@1 {
                algo = "crc32";
            };
            hash@2 {
                algo = "sha1";
            };
        };
    };

    configurations {
        default = "conf@1";
        conf@1 {
            description = "Boot Linux kernel with FDT blob";
            kernel = "kernel@1";
            fdt = "fdt@1";
        };
    };
};
Run Code Online (Sandbox Code Playgroud)

U-Boot输出:

Tegra124 (Jetson TK1) # fatload mmc 1 0x90000000 /kernel_fdt.itb
reading /kernel_fdt.itb
5946200 bytes read in 497 ms (11.4 MiB/s)
Tegra124 (Jetson TK1) # bootm 0x90000000
## Loading kernel from FIT Image at 90000000 ...
   Using 'conf@1' configuration
   Verifying Hash Integrity ... OK
   Trying 'kernel@1' kernel subimage
     Description:  Vanilla Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x900000ec
     Data Size:    5910168 Bytes = 5.6 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x00000000
     Entry Point:  0x00000000
     Hash algo:    crc32
     Hash value:   c5b4b377
     Hash algo:    sha1
     Hash value:   f001007efe83f563425bfe0659186a32395c946c
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 90000000 ...
   Using 'conf@1' configuration
   Trying 'fdt@1' fdt subimage
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x905a30ac
     Data Size:    34678 Bytes = 33.9 KiB
     Architecture: ARM
     Hash algo:    crc32
     Hash value:   e466b23e
     Hash algo:    sha1
     Hash value:   ec909ae16e62233d0ed1e1f4c909085abc9b5879
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x905a30ac
   Loading Kernel Image ... OK
   Using Device Tree in place at 905a30ac, end 905ae821

Starting kernel ...
Run Code Online (Sandbox Code Playgroud)

saw*_*ust 6

突出的问题是U-Boot输出文本后系统似乎挂起

Starting kernel ...
Run Code Online (Sandbox Code Playgroud)

如果已加载未压缩的内核映像文件,则接下来将执行实际的内核启动代码.
但是如果加载了uImagezImage文件(由于它们是自解压缩的,它们也被报告为"未压缩"),则执行的下一个代码将是附加到zImage文件的解压缩例程.通常,此解压缩例程将输出诸如的文本

Uncompressing Linux............ done, booting the kernel.
Run Code Online (Sandbox Code Playgroud)

在执行实际的内核启动代码之前,在内核命令行的任何处理之前,在任何处理Device Tree blob之前,以及在从内核输出任何控制台之前(包括earlyprintk).


图像头中指定的内核加载和起始地址之间存在差异

 Load Address: 0x00000000
 Entry Point:  0x00000000
Run Code Online (Sandbox Code Playgroud)

与DT中指定的内容相比:

        load = <0x81008000>;
        entry = <0x81008000>;
Run Code Online (Sandbox Code Playgroud)

由于内核映像是临时加载的

## Loading kernel from FIT Image at 90000000 ...
Run Code Online (Sandbox Code Playgroud)

DT中的地址似乎是正确的,图像标题中的地址是假的.

假设在0x00000000处没有物理RAM,结果将是内核映像被复制(或解压缩)到虚假加载地址0,然后内核映像将通过分支到伪造入口点0来执行. CPU可能会挂起尝试从不存在的内存中执行垃圾,这与您报告的内容完全相关.

解决方法是(1)确认内核链接到正确的地址,(2)使用和命令选项在mkimage命令中指定正确的地址. 这种修正至少应该让你超越这一点.-a-e


Cla*_*dio 2

使用设备树时,您仍然需要bootargs提供参数。

检查:

  • 您已经编译了树(使用编译器scripts/dtc/dtcLinux 内核内的编译器)
  • 内核配置中启用了对设备树的支持(符号CONFIG_USE_OF)(其中 OF 代表“开放固件”
  • 您向 U-Boot 提供了树的地址:bootm <uImage address> - <dtb address>
  • 串行控制台在设备驱动程序 -> 字符设备 -> 串行驱动程序下的内核配置中启用
  • 控制台已启用bootargs(例如,console=ttyS0,115200