13

I've been trying to understand the booting process, but there's just one thing that is going over my head..

As soon as the Linux kernel has been booted and the root file system (/) mounted, programs can be run and further kernel modules can be integrated to provide additional functions. To mount the root file system, certain conditions must be met. The kernel needs the corresponding drivers to access the device on which the root file system is located (especially SCSI drivers). The kernel must also contain the code needed to read the file system (ext2, reiserfs, romfs, etc.). It is also conceivable that the root file system is already encrypted. In this case, a password is needed to mount the file system.

The initial ramdisk (also called initdisk or initrd) solves precisely the problems described above. The Linux kernel provides an option of having a small file system loaded to a RAM disk and running programs there before the actual root file system is mounted. The loading of initrd is handled by the boot loader (GRUB, LILO, etc.). Boot loaders only need BIOS routines to load data from the boot medium. If the boot loader is able to load the kernel, it can also load the initial ramdisk. Special drivers are not required.

If /boot is not a different partition, but is present in the / partition, then shouldn't the boot loader require the SCSI drivers, to access the 'initrd' image and the kernel image? If you can access the images directly, then why exactly do we need the SCSI drivers??

20

Nighpher, I'll try to answer your question, but for a more comprehensive description of boot process, try IBM article.

Ok, I assume, that you are using GRUB or GRUB2 as your bootloader for explanation. First off, when BIOS accesses your disk to load the bootloader, it makes use of its built-in routines for disk access, which are stored in the famous 13h interrupt. Bootloader (and kernel at setup phase) make use of those routines when they access disk. Note that BIOS runs in real mode (16 bit) mode of processor, thus it can not address more than 2^20 bytes of RAM (2^20 not 2^16 because each address in real mode is comprised of segment_address*16 + offset, where both segment address and offset are 16-bit, see http://en.wikipedia.org/wiki/X86_memory_segmentation). Thus, these routines can't access more than 1 MiB of RAM, which is a strict limitation and a major inconvenience.

BIOS loads bootloader code right from the MBR - the first 512 bytes of your disk and executes it. If you're using GRUB, that code is GRUB stage 1. That code loads GRUB stage 1.5, which is located either in the first 32 KiB of disk space, called DOS compatibility region or from a fixed address of the file system. It doesn't need to understand file system to do this, cause even is stage 1.5 is in the file system, it is "raw" code and can be directly loaded to RAM and executed: http://www.pixelbeat.org/docs/disk/. Load of stage1.5 from disk to RAM makes use of BIOS disk access routines.

enter image description here

Stage1.5 contains the filesystem utilities, so that it can read the stage2 from filesystem (well, it still uses BIOS 13h to read from disk to RAM, but now it can decipher filesystem info about inodes etc. and get raw code out of the disk). Older BIOSes might not be able to access the whole HD due to limitations in their disk addressing mode - they might use Cylinder-Head-Sector system, unable to address more than first 8 GiB of disk space: http://en.wikipedia.org/wiki/Cylinder-head-sector.

Stage2 loads kernel into RAM (again, using BIOS disk utilities). If it's 2.6+ kernel, it also has initramfs compiled within, so no need to load it. If it's an older kernel, bootloader also loads standalone initrd image into memory, so that kernel could mount it and get drivers for mounting real file system from disk.

The problem is that kernel (and ramdisk) weigh more than 1 MiB, thus to load them into RAM you have to load kernel to first 1 MiB, then jump to protected mode (32 bit), move the loaded kernel to high memory (free the first 1 MiB for real mode), then return to real (16 bit) mode again, get ramdisk from disk to first 1 MiB (if it's a separate initrd and older kernel), possibly switch to protected (32 bit) mode again, put it to where it belongs, possibly get back to real mode (or not: https://stackoverflow.com/questions/4821911/does-grub-switch-to-protected-mode) and execute the kernel code. Warning: I'm not entirely sure about thoroughness and accuracy of this part of description.

Now, when you finally run the kernel, you already have it and ramdisk loaded into RAM by bootloader, so kernel can use disk utilities from ramdisk to mount you real root file system and pivot root to it. ramfs drivers are present in the kernel, so it can understand the contents of initramfs, of course.

  • Can't the bootlader just load the kernel in chunks, instead of jumping into protected mode?? And what is the need for freeing that 1 MB..(Sorry.. couldn't understand that..) – rpthms Sep 9 '13 at 10:41
  • The need for freeing first 1MiB is as follows: bootloader can access your hard drive only in real mode, cause it accesses it with BIOS utilities, which are real-mode (they operate on 16-bit arguments and use 16-bit operations). Real mode just doesn't see any RAM except by first 1 MiB. But you need to load kernel+initramfs into RAM and they take ~5 MiB space in RAM. Those BIOS utilities just won't be able to squeeze 5 MiB into the first 1 MiB. So, bootloader has to copy them from disk to first 1 MiB, then go to protected mode and move them from first 1Mb RAM to higher RAM. Is it clearer now? :) – Boris Burkov Sep 9 '13 at 11:04
  • 1
    The whole stage 1/1.5/2 stuff is grub legacy. – psusi Sep 9 '13 at 14:10
  • 1
    @CMCDragonkai Yes, stage2 bootloader is in the filesystem (namely, in /boot partition). Kernel is not loaded at this point - it's grub's stage1.5, who's accessing stage2 in the /boot filesystem (e.g. in /boot/grub file) via its minimalistic filesystem drivers. Kernel will also be able to read from /boot partition, but it will happen later, after execution of grub2 code and load of kernel and after kernel reads initramfs. Are you speaking of init.sh of the initramfs? It resides in /boot partition of your hard drive, then stage2 of grub puts it into RAM and Kernel reads it from RAM. – Boris Burkov Dec 3 '15 at 8:44
  • 1
    Initrd had to be a separate file. The newer initramfs can be linked to the kernel, but it does not have to be - it can also be loaded as a separate file by the bootloader. Since the initramfs file is defined as a sequence of cpio archives, some bootloaders (e.g. iPXE) even allow multiple initramfs files, which will be loaded into memory one after another. Also, some Linux distributions use initrd-style file names for backwards compatibility, although the actual technology used is now initramfs. – telcoM Mar 28 at 7:55
1

I believe, it boils down to what features particular bootloader supports. Eg. it doesn't have to know particular filesystem of your combined (boot + root) partition. In that case you just create a separate boot partition in condition such that it works with your bootloader, and any other complexity of how to mount your root partition is left on the kernel and initrd image booted from boot partition. Bootloader does know how to access the SCSI devices (and other devices too, depending on what bootloader is used) either by using it's own drivers or by utilizing BIOS routines. Moreover, it knows how to read some filesystems, etc.

Consider eg. UEFI way of booting, where actually UEFI firmware already know how to access EFI partition, read it and load linux kernel from there without need of intermediate bootloader. In that case the linux image lives separated from root partition and UEFI firmware doesn't have to know all exotic filesystems to access it. I believe separation of "boot" images from "root" partition make big sense. If not for anything else then this is necessity when setting up root filesystem encryption.

0

Just for the record, if a bootloader does not load initrd it's worthwhile to test another bootloader; I've just ran into a situation like this when LILO silently ignored a properly specified initrd of medium size (<4Mb; single ext4 rootfs on a SATA SSD; GPT) and GRUB 2.00 succeeded.

The boot process ended quickly with a typical

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)

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.