The Linux kernel command-line

Published on July 23, 2012

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.

The Linux kernel has a lot of features that can be controlled at boot time through a feature known as the "Kernel command line". When combined with a U-Boot variable named bootargs, this feature allows you to tell the kernel how to configure various device drivers, where to find the root filesystem and can even be used to pass information to applications on the system.

The next time you boot Linux, I encourage you to pay attention to the start of the kernel's output to the serial port:

Uncompressing Linux... done, booting the kernel. Initializing cgroup subsys cpuset Initializing cgroup subsys cpu Linux version 3.0.15-ga753097 (gcc version 4.4.3 (GCC) )... CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c53c7d CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache Machine: Freescale i.MX 6Quad Sabre-Lite Board Memory policy: ECC disabled, Data cache writealloc PERCPU: Embedded 7 pages/cpu @c10fa000 s5760 r8192 d14720 u32768 Built 1 zonelists in Zone order, mobility grouping on. Total pages: 198656 Kernel command line: console=ttymxc1,115200 init=/init rw no_console_suspend androidboot.console=ttymxc1 vmalloc=400M video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 video=mxcfb1:dev=lcd,CLAA-WVGA,if=RGB666 fbmem=28M,10M,10M calibration tsdev=tsc2004 video=mxcfb2:dev=ldb,LDB-XGA,if=RGB666 The last four lines above show a rather complicated set of flags and variable assignments used in a boot of Android on the Nitrogen6X board. I'll walk through a number of them below, but first I'd like to talk about how and where these variables are set and handed off to the kernel.

The short answer to that question is U-Boot, but the more precise answer is that the U-Boot boot loader passes the kernel command-line transparently to the Linux kernel using a feature known as atags from a U-Boot variable named bootargs. In general, you won't need to know about atags, but if you mess around at all with U-Boot, you're likely to know a lot about bootargs.

Structure and construction

In lots of previous posts, we've described the anatomy and particulars of boot scripts. One of the primary purposes of those scripts is to construct a proper set of bootargs for the user-space being booted.

If you run print at a U-Boot prompt, you're likely to see something like this that defines a default set of bootargs. U-Boot > print bootdelay=3 ... bootargs=console=ttymxc1,115200 video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 This example just shows a set of default values in bootargs. This is typical of a configuration set by Boundary Devices. You might also see something like this, which is more typical of Freescale:
U-Boot > print bootargs_base=setenv bootargs console=ttymxc1,115200 ... bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp video=mxcfb0:dev=ldb,LDB-XGA,if=RGB666 enable_wait_mode=off bootcmd_net=dhcp; run bootargs_base bootargs_nfs;bootm The notable difference between the two is that the value of the bootargs_base and bootargs_nfs variables are actually a set of commands that set and append to the variable bootargs respectively.
Likewise, the bootcmd_net variable contains commands which will run the other two. In typical usage, bootcmd_net will be invoked by the first level bootcmd variable like so:

U-Boot > print ... bootcmd=run bootcmd_net

Our practices

That's a lot of running, and the primary reason we tend to avoid this is that it's not clear what you're saving. In other words, this mixes code and data, which can cause things to break.

Our desire to separate things also stems from our practice of booting to SPI-NOR and not the same device that contains our root filesystem. Most Freescale devices are configured to use a single media (usually SD card) for both.

Since we have separate storage for them, we try and place variables which define the board, such as display configuration or mac addresses into persistent environment variables and leave variables that are tied to the user-space in a boot script which follows the boot media.

Common variables

The following is a table of commonly used bootargs components. Note that these change with kernel releases and updates to the userspace, so we suggest that you ask us or your user-space provider for specifics during each release.

NameTypical valuesDescription
video= mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 Used to specify the display resolution on i.MX6.
root= /dev/mmcblk0p1 Used to specify the root filesystem. This is required unless a RAM disk is specified in the U-Boot bootm command.
rootwait N/A This flag should always be present if a root= clause is specified. It tells the kernel to wait for the device to appear before trying to mount it.
console= ttymxc1,115200 Used to specify the Linux kernel console device (to which kernel messages are routed).
init= /init After mounting the root filesystem, the Linux kernel runs a single program to start the system. This is typically either /init or /linuxrc. You can override the default behavior if your userspace requires it by using the init= parameter. Note that this is rarely needed.