如何在ARM上设置Linux内核命令行?

use*_*522 3 command-line arm linux-kernel embedded-linux device-tree

我的理解是,对于 ARM,内核启动命令行一般有以下三个来源:

  1. 那些在内核配置中作为 CONFIG_CMDLINE 给出的
  2. 由引导加载程序传递的那些(通常是 ARM 处理器上的 U-Boot)
  3. 那些包含在设备树中的 selected/bootargs 下使用哪一个取决于内核配置参数。我的问题是如何使用内核配置在这些选项之间进行选择?

一个可以附加到另一个,即我们可以使用 CONFIG_CMDLINE 传递一些参数,然后在设备树中附加硬件特定参数吗?

我首先尝试组合 1、2 和 3,但这无法编译:

/dts-v1/; 
#include "imx6q.dtsi"
#include "imx6q-h.dtsi"
#include "imx6q-m.dtsi"
/ {
    model = "A M";
    compatible = "a,imx6q-hydra13", "a,imx6q-mercury",
                    "a,imx6q-hydra", "fsl,imx6q";
};

&ssd_touch {
    status = "okay";
};

ERROR AT THIS LINE: chosen {  
        bootargs = "console=ttymxc1,115200";
};
Run Code Online (Sandbox Code Playgroud)

saw*_*ust 5

我的理解是,对于 ARM,内核启动命令行一般有以下三个来源:

这对于 Linux ARM 内核来说并不准确。内核只处理两个“源”,一个default kernel command字符串和一个bootloader kernel arguments字符串。
更多详细信息如下。

我的问题是如何使用内核配置在这些选项之间进行选择?

您的选择可能仅限于“使用内核配置”

“附加”命令行配置选项,即 CONFIG_CMDLINE_FROM_BOOTLOADER(“bootloader kernel arguments如果可用则使用”)、CONFIG_CMDLINE_EXTEND(“扩展bootloader kernel arguments”)和 CONFIG_CMDLINE_FORCE(“始终使用字符串default kernel command”)仅在支持旧版本时可用(自版本 3.7 起) ATAG 参数传递(即 CONFIG_ATAGS)已启用。
但是,除非明确禁用,否则 CONFIG_ATAGS 确实默认为y。主线arch/arm/configs/中大约有十几个_defconfig文件明确禁用了此 CONFIG_ATAGS。


但是设备树在这个方案中处于什么位置呢?

设备树是bootloader kernel arguments.
也就是说,节点bootargs=中的属性/chosen是向ARM 内核提供命令行的传统方法,即当CONFIG_ATAGS 被禁用时,或者CONFIG_CMDLINE_FROM_BOOTLOADER 或CONFIG_CMDLINE_EXTEND 被启用时。
内核通过drivers/of/fdt.c中的Early_init_dt_scan_chosen()从设备树中以字符串形式检索命令行

仅当启用 CONFIG_CMDLINE_FORCE(使用 CONFIG_ATAGS)时,设备树bootargs=属性才会被忽略。

您可以使用 CONFIG_CMDLINE 配置/构建 ARM 内核default kernel command,以防没有其他方法可以设置命令行。drivers/of/fdt.c
中的注释记录了这一点。

bootargs=CONFIG_CMDLINE_EXTEND(与 CONFIG_ATAGS)生成的命令行是设备树属性与 CONFIG_CMDLINE 内容的串联。

然而 ...

使用 U-Boot 引导 Linux 内核时,请注意,bootargs定义环境变量后,U-Boot 会(尝试)将该bootargs环境变量(作为属性)安装到/chosen已加载的设备树 blob 的节点中。
如果/chosenDT 中不存在该节点,则创建该节点。
如果该bootargs=属性在该 DT 节点中不存在,则创建它。
如果该bootargs=属性已存在于该 DT 节点中,则会使用 U-Boot 环境变量覆盖该属性。
请参阅common/fdt_support.c中的fdt_chosen()

IOW U-Boot 的bootargs环境变量通常成为事实上的内核命令行。


一个可以附加到另一个,即我们可以使用 CONFIG_CMDLINE 传递一些参数,然后在设备树中附加硬件特定参数吗?

bootargs仅当 (a) CONFIG_ATAGS 启用,并且 (b) CONFIG_CMDLINE_EXTEND 启用,并且 (c) 确保U-Boot 环境中没有变量。


底线

  1. U-Boot 总是尝试使用设备树将其变量传递bootargs给内核。
  2. 设备树中的属性bootargs=始终由内核使用,如arch/arm/Kconfigbootloader kernel arguments文件中所述。