Search code examples
linux-kernelboot

how does the bootloader pass the kernel command line to the kernel?


We can see the kernel command line like this :

ckim@chan-ubuntu:~/$ cat /proc/cmdline  
BOOT_IMAGE=/boot/vmlinuz-4.15.0-122-generic root=UUID=99c66a0a-39c1-451c-9f72-ad1576aafb41 ro quiet splash

This command line seems to be what grub has passed to the kernel for booting. How is this command line actually passed to the kernel program? I guess maybe the command line is loaded in memory as a string and a register of the processor (like x1, if arm64 processor) is set to that string address? I'm interested in arm64 case especially.


Solution

  • The same question sometimes popped up to me. So this is a moment to deep dive.

    While x86 uses special protocol for booting Linux, in the case of arm64 a different scheme is used. For communication with kernel, boot loader puts only single address - loaded flatten device tree (FDT) into the x0 register.

    Here is excerpt from Linux and the Device Tree, Runtime configuration:

    In most cases, a DT will be the sole method of communicating data from firmware to the kernel, so also gets used to pass in runtime and configuration data like the kernel parameters string and the location of an initrd image.

    Most of this data is contained in the /chosen node, and when booting Linux it will look something like this:

    chosen {
            bootargs = "console=ttyS0,115200 loglevel=8";
            initrd-start = <0xc8000000>;
            initrd-end = <0xc8200000>;
    };
    

    Here is another example of DT.

    Next, during kernel early boot, the OF/FDT module parses the passed device tree and fill in boot_command_line variable.