How to set Linux kernel command line on ARM?
Asked Answered
T

1

3

My understanding is that for ARM there are three sources for the kernel boot command line in general:

  1. Those given as CONFIG_CMDLINE in the kernel configuration
  2. Those passed on by the boot loader (typically U-Boot on ARM processors)
  3. Those included in the device tree, under chosen/bootargs Which one is used depends on kernel configuration parameters. My question is how to choose between these options using kernel configuration?

And can one append to another i.e. can we pass some using CONFIG_CMDLINE and then append hardware specific parameters in device tree?

I'm trying combination 1, 2 AND 3 to begin with but this doesn't compile:

/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";
};
Tenure answered 8/7, 2021 at 19:12 Comment(4)
how many combinations did you try and what were your results, please post the experiments and resultsTribulation
CONFIG_CMDLINE sets the default kernel command string. Then there is a choice of these options: (1) CONFIG_CMDLINE_FROM_BOOTLOADER will use the command line from bootloader in preference to the the default kernel command string. (2) CONFIG_CMDLINE_EXTEND will append the command line from the bootloader to the default kernel command string. (3) CONFIG_CMDLINE_FORCE will only use the default kernel command string, ignoring any provided by the boot loader.Mitzi
The error is probably because your chosen node is outside the root node.Mitzi
@IanAbbott Thank you. But where does the device tree fit in this scheme of things? I am using AOSP 9 code and set the command line in BoardConfig.mk file AND the device tree but I don't see the device tree command line showing up anywhere including /proc/cmdline.Tenure
K
6

My understanding is that for ARM there are three sources for the kernel boot command line in general:

That's not accurate for the Linux ARM kernel. The kernel only deals with two "sources", a default kernel command string and a bootloader kernel arguments string.
More details follow.

My question is how to choose between these options using kernel configuration?

You choices may be limited by only "using kernel configuration".

The "additional" command-line configuration choices, i.e. CONFIG_CMDLINE_FROM_BOOTLOADER ("Use bootloader kernel arguments if available"), CONFIG_CMDLINE_EXTEND ("Extend bootloader kernel arguments"), and CONFIG_CMDLINE_FORCE ("Always use the default kernel command string") are only available (since version 3.7) when support for the old ATAGs parameter passing (i.e. CONFIG_ATAGS) is enabled.
However CONFIG_ATAGS does default to y unless explicitly disabled. About a dozen _defconfig files in mainline arch/arm/configs/ do explicitly disable this CONFIG_ATAGS.


But where does the device tree fit in this scheme of things?

The Device Tree is the provider of bootloader kernel arguments.
That is, the bootargs= property in the /chosen node, is the conventional method of providing the command line to the ARM kernel, i.e. when CONFIG_ATAGS is disabled, or either CONFIG_CMDLINE_FROM_BOOTLOADER or CONFIG_CMDLINE_EXTEND are enabled.
The command line is retrieved by the kernel from the Device Tree as a string by early_init_dt_scan_chosen() in drivers/of/fdt.c

Only if CONFIG_CMDLINE_FORCE (with CONFIG_ATAGS) are enabled will the Device Tree bootargs= property be ignored.

You can configure/build the ARM kernel with a default kernel command using CONFIG_CMDLINE in case nothing else managed to set the command line.
A comment in drivers/of/fdt.c documents this.

CONFIG_CMDLINE_EXTEND (with CONFIG_ATAGS) results in a command line that is the concatenation of the Device Tree bootargs= property with the contents of CONFIG_CMDLINE.

However ...

When using U-Boot to boot the Linux kernel, be aware that when the environment variable bootargs is defined, U-Boot will (try to) install that bootargs environment variable (as a property) into the the /chosen node of the loaded Device Tree blob.
If the /chosen node does not exist in the DT, then it is created.
If the bootargs= property does not exist in that DT node, then it is created.
If the bootargs= property already exists in that DT node, then it is overwritten with the U-Boot environment variable.
See fdt_chosen() in common/fdt_support.c.

IOW U-Boot's bootargs environment variable typically becomes the de facto kernel command line.


And can one append to another i.e. can we pass some using CONFIG_CMDLINE and then append hardware specific parameters in device tree?

Only if (a) CONFIG_ATAGS is enabled, and (b) CONFIG_CMDLINE_EXTEND is enabled, and (c) ensure that there is no bootargs variable in U-Boot's environment.


Bottom Line

  1. U-Boot always tries to pass its bootargs variable to the kernel using the Device Tree.
  2. The bootargs= property in the Device Tree is always used by the kernel as the bootloader kernel arguments as mentioned in the arch/arm/Kconfig file.
Killer answered 11/7, 2021 at 23:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.