Boot Process in Linux

Adity RoyAdity Roy
8 min read

There are 6 high-level stages involved in a Linux boot process.

  1. BIOS (basic input output system)/UEFI (Unified Extensible Firmware Interface)

    The major function of BIOS is to load and execute the MBR boot loader.

    BIOS and UEFI are firmware interfaces that computers use to boot up the operating system (OS). Yet, the two programs differ in how they store metadata on and about the drive:

    • BIOS uses the Master Boot Record (MBR)

    • UEFI uses the GUID Partition Table (GPT)

It performs an integrity check on SSD and HDD. It searches, loads and executes boot loader programs. It looks for a boot loader in floppy, cd-rom, or hard drive and once the boot loader program is detected and loaded into the memory, BIOS gives control to it. During BIOS startup, you can press the "F2"/"F12" key to change the boot sequence.

BIOS POST checks the basic operability of the hardware and then it issues a BIOS interrupt, INT 13H, which locates the boot sectors on any attached bootable devices. The first boot sector it finds that contains a valid boot record is loaded into RAM and control is then transferred to the code that was loaded from the boot sector.

  1. MBR Bootloader (master boot record)

    The major function of MBR Bootloader is that it loads and executes the GRUB bootloader.

    MBR is located in the first sector of the bootable disk. Typically /dev/hda, or /dev/sda.
    It is less than 512 bytes in size which is divided between its 3 components.

    1. 446 bytes for primary boot loader info

    2. 64 bytes for partition table info

    3. last 2 bytes for MBR validation check

It also contains information about GRUB.

On the other hand, a UEFI system stores all startup data in an .efi file. The file is on the EFI System Partition, which contains the boot loader.

To view boot messages, use

  1. dmesg

  2. /var/log/dmesg

  1. GRUB (grand unified bootloader)
    GRUB just loads and executes Kernel and initrd(initial ram disk) images.

    In case you have multiple kernel images installed in your system, you can choose which one to be executed. GRUB displays a splash screen, and waits for a few seconds, if you don’t enter anything, it loads the default kernel image as specified in the grub configuration file. GRUB has knowledge of the filesystem.
    Grub configuration file is /boot/grub/grub.conf (/etc/grub.conf is a link to this). The following is sample grub.conf of CentOS.

     #boot=/dev/sda
     default=0
     timeout=5
     splashimage=(hd0,0)/boot/grub/splash.xpm.gz
     hiddenmenu
     title CentOS (2.6.18-194.el5PAE)
               root (hd0,0)
               kernel /boot/vmlinuz-2.6.18-194.el5PAE ro root=LABEL=/
               initrd /boot/initrd-2.6.18-194.el5PAE.img
    

    Features of GRUB2:

    • ability to boot multiple operating systems

    • boots both a graphical and a text-based interface

    • allows ease of use over a serial cable

    • strong command line interface for interactive configuration

    • network-based diskless booting

  2. Kernel
    It mounts the root file system as specified in the “root=” in grub.conf. Kernel executes the /sbin/init program. I**nit was the 1st program to be executed by Linux Kernel, it has the process id *(*PID) of 1. Do a ‘ps -ef | grep init’ and check the pid.

    Initrd is used by the kernel as a temporary root file system until the kernel is booted and the real root file system is mounted.

    It also contains necessary drivers compiled inside, which helps it to access the hard drive partitions, and other hardware.
    The operating system now controls access to our computer resources.

    Here, the Linux kernel follows a predefined procedure:

    1. decompress itself in place

    2. perform hardware checks

    3. gain access to vital peripheral hardware

    4. run the init process

Next, the init process continues the system startup by running init scripts for the parent process. Also, the init process inserts more kernel modules (like device drivers).

  1. Init/Systemd/SysVinit

    the parent of all Linux processes is Systemd, which replaces the old SysVinit process. Following the booting steps, Systemd performs a range of tasks:

    • probe all remaining hardware

    • mount filesystems

    • initiate and terminate services

    • manage essential system processes like user login

    • run a desktop environment

Indeed, these and other tasks allow users to interact with the system. Lastly, Systemd uses the /etc/systemd/system/default.target file to decide the state or target the Linux system boots into.
Looks at the /etc/inittab file to decide the Linux run level.
Following are the available run levels

  • 0 – halt

  • 1 – Single user mode

  • 2 – Multiuser, without NFS

  • 3 – Full multiuser mode

  • 4 – unused

  • 5 – X11

  • 6 – reboot

Init identifies the default initlevel from /etc/inittab and uses that to load all appropriate programs. Execute grep initdefault /etc/inittab on your system to identify the default run level.

If you want to get into trouble, you can set the default run level to 0 or 6. Since you know what 0 and 6 means, probably you might not do that. Else

set the default to level 3 0r 5.

  1. Runlevel Programs

    When the Linux system is booting up, you might see various services getting started. For example, it might say “starting sendmail …. OK”. Those are the runlevel programs, executed from the run level directory as defined by your run level.

    The link between run level numbers and targets:

    1. poweroff.target, run level 0: turn off (shut down) the computer

    2. rescue.target, run level 1: initiate a rescue shell process

    3. multi-user.target, run level 3: configure the system as a non-graphical (console) multi-user environment

    4. graphical.target, run level 5: establish a graphical multi-user interface with network services

    5. reboot.target, run level 6: restart the machine

    6. emergency.target: emergency run level

Depending on your default init level setting, the system will execute the programs from one of the following directories.

    • Run level 0 – /etc/rc.d/rc0.d/

      • Run level 1 – /etc/rc.d/rc1.d/

      • Run level 2 – /etc/rc.d/rc2.d/

      • Run level 3 – /etc/rc.d/rc3.d/

      • Run level 4 – /etc/rc.d/rc4.d/

      • Run level 5 – /etc/rc.d/rc5.d/

      • Run level 6 – /etc/rc.d/rc6.d/

To check default target run-level, use - systemctl get-default

  • There are also symbolic links available for these directory under /etc directly. So, /etc/rc0.d is linked to /etc/rc.d/rc0.d. Under the /etc/rc.d/rc*.d/ directories, you would see programs that start with S and K.

  • Programs starting with S are used during startup. S for startup and programs starting with K are used during shutdown. K for kill. There are numbers right next to S and K in the program names. Those are the sequence number in which the programs should be started or killed.

    For example, S12syslog is to start the syslog deamon, which has the sequence number of 12. S80sendmail is to start the sendmail daemon, which has the sequence number of 80. So, syslog program will be started before sendmail.

Terminology:

  1. Boot Sector is the sector of a persistent data storage device (e.g., hard disk, floppy disk, optical disc, etc.) which contains machine code to be loaded into random-access memory (RAM) and then executed by a computer system's built-in firmware (e.g., the BIOS).

    A disk can be partitioned into multiple partitions and, on conventional systems, it is expected to be. There are two definitions on how to store the information regarding partitioning:

    A Master Boot Record (MBR) is the first sector of a data storage device that has been partitioned. The MBR sector may contain code to locate the active partition and invoke its volume boot record.

    A Volume Boot Record (VBR) is the first sector of a data storage device that has not been partitioned or the first sector of an individual partition on a data storage device that has been partitioned. It may contain code to load an operating system (or another standalone program) installed on that device or within that partition.

  2. kernel images is a binary form of the operating system core, nicknamed the kernel, that a bootloader can use to start the OS. In a YP context, this will almost always be a Linux kernel. The expression image there literally means one file that is the executable form of the Linux kernel. the same wording is used by the Linux Kernel devs too, by the way.

  3. A daemon is a service process that runs in the background and supervises the system or provides functionality to other processes.

  4. You can bypass the first three stage using kexec program for fast boot. This saves time when you have to reboot a lot for tuning system or handling init script.

    Debian provides it as kexec-tools package.

    Find the kernel options:
    $ cat /proc/cmdline
    BOOT_IMAGE=/vmlinuz-3.4.0-10.dmz.1-liquorix-amd64 root=UUID=07cf8c3a-d5a5-4b41-833f-16a9afebf70c ro quiet

    Add a kernel image:
    vmlinuz is the kernel image file I uses. If the kernel image uses initrd file, add –initrd option. Without it kernel will panic next boot.

    $ sudo kexec -l /vmlinuz –append=”root=UUID=07cf8c3a-d5a5-4b41-833f-16a9afebf70c
    ro quiet” –initrd=/initrd.img

    Or

    In my Linux box, boot partition is /dev/sda1
    $ sudo kexec -l /vmlinux –append=”root=/dev/sda1 ro quiet” –initrd=/initrd.img

    Start warm boot:
    $ sudo kexec -e

    Linux will boot up without going through BIOS, MBR, and Grub.

  5. vmlinux

    This is the Linux kernel in an statically linked executable file format. Generally, you don't have to worry about this file, it's just a intermediate step in the boot procedure.

    The raw vmlinux file may be useful for debugging purposes.

    vmlinux.bin

    The same as vmlinux, but in a bootable raw binary file format. All symbols and relocation information is discarded. Generated from vmlinux by objcopy -O binary vmlinux vmlinux.bin.

    vmlinuz

    The vmlinux file usually gets compressed with zlib. Since 2.6.30 LZMA and bzip2 are also available. By adding further boot and decompression capabilities to vmlinuz, the image can be used to boot a system with the vmlinux kernel. The compression of vmlinux can occur with zImage or bzImage.

    The function decompress_kernel() handles the decompression of vmlinuz at bootup, a message indicates this:

     Decompressing Linux... done
     Booting the kernel.
    

    zImage (make zImage)

    This is the old format for small kernels (compressed, below 512KB). At boot, this image gets loaded low in memory (the first 640KB of the RAM).

    bzImage (make bzImage)

    The big zImage (this has nothing to do with bzip2), was created while the kernel grew and handles bigger images (compressed, over 512KB). The image gets loaded high in memory (above 1MB RAM). As today's kernels are way over 512KB, this is usually the preferred way.


References:

[1] https://www.thegeekstuff.com/2011/02/linux-boot-process/

[2]https://en.wikipedia.org/wiki/Boot_sector#:~:text=A%20boot%20sector%20is%20the,(e.g.%2C%20the%20BIOS).

[3] https://www.geeksforgeeks.org/how-linux-kernel-boots/

[4] https://www.baeldung.com/linux/boot-process

[5] https://opensource.com/article/17/2/linux-boot-and-startup

[4]http://mbrwizard.com/thembr.php#:~:text=Located%20in%20the%20final%20two,booting%20or%20using%20the%20disk

[5]https://unix.stackexchange.com/questions/5518/what-is-the-difference-between-the-following-kernel-makefile-terms-vmlinux-vml

0
Subscribe to my newsletter

Read articles from Adity Roy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Adity Roy
Adity Roy