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
- U-Boot always tries to pass its
bootargs
variable to the kernel using the Device Tree.
- 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.
chosen
node is outside the root node. – Mitzi