Considering that GRUB executes following lines:

kernel /vmlinuz root=/dev/sda1 ro
initrd /initrd

On boot, how does the Linux kernel finds out about /dev/sda1 device node?

I know that initrd/initramfs images contain modules for storage (etc.) devices, which are loaded into memory to enable access to the storage. What bugs me, is how exactly the kernel parameter root=/dev/sda1 is parsed by the kernel.

Does the /init (or /linuxrc) script in initrd/initramfs creates the /dev directory and then the device node /dev/sda1 in it? Or the "major" and "minor" numbers for /dev/sda1 are hardcoded in the kernel?


If you have an initramfs the kernel just unpacks and mounts the initramfs and executes /init afterwards. Everything else will be handled by the /init executable. This also means the kernel doesn't mount the device specified in the root boot parameter.

Different Distributions use different initramfs frameworks like e.g. dracut for Fedora or initramfs-tools for Debian. Most common solutions are either using something like udev, mdev or devtmpfs. Some may also just use MAKEDEV to generate a static layout or have the device files already integrated into their image.

If you boot without an initramfs the kernel can just boot from devices with known major/minor numbers, e.g. /dev/sda1 but not from lvm devices.


The major any minor numbers of the root device are stored in the kernel image (see manpage of rdev for more information).

Yet, the kernel commandline arguments are NOT interpreted by the kernel. The initial ramdisk, initrd, contains a filesystem with a minimal linux which usually does the interpreting part. How the initrd works depends on your distribution. It may simply contain the node /dev/sda1 or some script/programm that creates it at runtime.

If you're on a Debian based Linux you can unpack your ramdisk like so:

mkdir /tmp/initrd
cd /tmp/initrd
zcat /boot/path/to/initrd | cpio -iv

The debian initrds are scripts and you can have a look at how it works. After the kernel has unpacked the initrd it launches the script init which you should now find in /tmp/initrd. Note the block where it says for x in $(cat /proc/cmdline); do.

In /proc/cmdline are the arguments passed using Grub (you can check/verify that right now with your shell!). If you care to dive a little deeper into Debians initrd you will note that you can make your kernel/initrd use a NFS share as root file system by passing the option root=/dev/nfs with Grub. When you do, no node /dev/nfs is created or mounted. It just tells the initrd what to do.

In the end every such initrd will run the command provided by some option like init= or the default /sbin/init

Coming back to your initial question in the headline: yes /init (most likely) creates that node at runtime. It uses all kinds of programms/heuristics/voodoo to figure out how to mount your root filesystem.


The initial code runs a program called mdev which is basically a cut-down version of udev. This scans all the devices and creates the initial contents of the /dev folder. The kernel is then able to effectively execute mount /dev/sda1 / and start finding the full system.

See here is you want to know more about mdev.

Major and minor device numbers are actually hardcoded into those kernel modules which are device drivers and which use static major numbers (see, for example, Documentation/devices.txt in the kernel sources). Most (all?) disk driver kernel modules would fall into this category. So, as @Ulrich Dangel says, some kernels can boot without an initramfs/initrd as long as the needed modules are statically linked to the kernel image.

  • Just for the record this is implementation specific, Debian for example uses udev and doesn't use mdev – Ulrich Dangel Jul 22 '12 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.