Linux – How is a Linux kernel capable of accessing its assigned initramfs/initrd

boot-loaderinitramfslinux-kernel

I'm trying to understand the boot process of a machine as a whole from the time you hit the power button. There's this one piece from bootloader to initramfs stage I don't quite understand among some other smaller bits.

Given this Grub configuration for an entry, taken from a recent Ubuntu default installation:

insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 96fb7310-5adb-4f66-bf59-04acd08d76a3
echo    'Loading Linux x.y.z ...'
linux   /vmlinuz-x.y.z root=/dev/mapper/some-device-name ro nomodeset 
echo    'Loading initial ramdisk ...'
initrd  /initrd.img-x.y.z

What does this actually do in terms of the system state and memory? I understand that Grub's task is to "load and run the kernel" and it has its own set of modules to access files on devices (or network) to get to them. In the example here insmods, set root and search – but this is just from the perspective of Grub, and not shared with the kernel, right?

I'm also guessing that Grub is loading (a copy?) of the kernel into memory (linux command) and kicking it to start execution. (two different steps apparently – so, how?) The parameters given can be read in the kernel and interpreted (is this a big string mapped into memory somewhere?) and provide the options to arrange things requested.

I also see this initrd option. This points to my gzip-compressed initramfs, needed to boot the actual root device specified by root=. But how is this initramfs provided to the kernel? It is not passed any memory addresses to where it can load it, nor is it able to access it itself, as it is loaded already before the kernel is started. Some kernel documentation says this initramfs file system 'device' is accessible through /dev/ram0, but I don't see how it becomes an accessible device file to start with. There's something happening under water I don't see, I guess.

I also don't see how this relates to other boot loaders, including embedded platforms, for example using U-boot/Coreboot. Is this doing the same thing as Grub (same standard memory addresses?) and to what extent does these compare to Grub regarding loading kernel/initrd?

Just to be clear on my questions, I think I do understand why the different boot stages exist and what transitions take place, yet I don't see how they take place and what the exact responsibilities are to each of the stages. I have the feeling I'm missing out on some "standard" to which this all comes down to.

I would appreciate some explanation on this.

Best Answer

In general there has to be some kind of protocol because typically it is not enough to just load a file into memory and jump at a specific location but you have to either pass additional arguments like kernel parameters, i.e. accessing memdisk arguments from DOS.

As this is hardware dependent (arm is different than x86 for instance) you have to find the correct information, see this article about booting arm or the Linux/x86 boot protocol for some examples.

Related Question