Understanding Booting Process and Runlevels in Linux

Hello everyone!

In this article, I will give you an in-depth understanding of the Linux booting process.

Booting Process

  1. Power is supplied, CPU started and then BIOS code is loaded. This performs basic low-level tests on the system, basic diagnostic (BIOS code test, Memory test, DMA, Interrupts).
  2. BIOS code searches for bootable devices like hard drives which is called a boot loader program.
  3. Boot loader locates and starts the kernel, once the kernel is started it performs its own system tests.
  4. First system process is created called init (pid1)
  5. Kernel takes a backseat and init takes over, init executes scripts that is required to get the system to that runlevel and spawn the processes that we need to present us with login prompts.

Understanding the Boot Process in depth

  • BIOS code is located in a well-known location in memory usually an NVRAM such as flash memory directly on the motherboard of the machine. The location is well-known means that it is hard-wired into the CPU as a reference to the first instruction that the CPU fetches and executes.
  • BIOS first runs POST (Power On Self Test) routine, it enumerates the touch devices, and performs basic hardware checks against them, and makes sure they are working well together without affecting all over each other.
  • Next BIOS then loads and executes some small runtime boot code that searches a list of bootable devices looking for a special program called a bootloader.
  • BIOS looks for the bootable device (Hard drive, Removable devices, etc) and finds MBR which is always on the first sector of bootable devices.
  • MBR is located in the first 512 bytes sector of the bootable device contains three things:
    • Stage1 Bootloader (446 bytes): This is low-level, hardcore, and machine code. The bootloader in Linux generally is GRUB (Grand Unified Boot Loader).
    • Partition Table (64 bytes)
    • Magic Number (2 bytes)
  • After that, another Stage2 bootloader is called which is more intelligent than the previous Bootloader. Then the next step is to load initramfs into memory and begin executing the kernel.
  • Now kernel comes in and first it takes the flag and takes a bunch of memory for itself and this memory is not used by another non-kernel process. Then kernel probes for other devices network cards, video cards, etc, and initializes the device drivers and makes them fully operational.
  • Finally, the first process init starts /sbin/init with process id of 1 (PID 1) with the parent process ID of PPID 0 indicating the kernel.
  • Kernel is done and now it hands over to init. The init first reads the /etc/inittab file to determine the runlevels of the system which runs the rc.sysinit script which does things like set the hostname, create the pseudo filesystem like procfs and sysfs, starts SELinux, initialize any logical volumes, and the checks and mount the filesystem.
  • After that file is run init then runs all the files associated with them (ls /etc/rc.d/rc3.d) with a simple algorithm.
  • Finally, init spawns login process to watch out for logins on all of the configured log-in terminals.

GRUB Boot Loader


    ------------------------ Boot ----------------------------->

    +------------+  +--------------+    +----------------------+
    | Stage 1    |  | Stage 1.5    |    |       Stage 2        |
    | ~400 bytes |  | FS drivers.. |    | /boot/grub/grub.conf |
    +------------+  |   ~30 KB     |    |      Menu, CLI..     | 
                    +--------------+    +----------------------+
        ^                 ^                         ^
        |                 |                         |
        V                 V                         V
    +-----------------------------------------------------------+
    | MBR  |            GAP           |  Partition Filesystem   |
    +-----------------------------------------------------------+

    |______________________ Drive ______________________________|

In stage 1 we have got 400 bytes of stage 1 GRUB machine code in sector 0 or MBR. This loads and executes the stage 1.5 boot loader. This is usually installed in either the boot partition or a bit of free space between the end of MBR and the start of the first partition on the drive, just called GAP. In this area between MBR and the first partition, there is a very small space of less than 32KB to play with it. Bigger than MBR but not a massive amount of room. This is enough space of 1.5 bootloaders to contain small device drivers that allow it to read file systems and this is crucial because the stage 1.5 bootloader can read file systems and opens up a whole new world to us.

This means that the next boot loader phase i.e stage 2 boot loader, can be called from the filesystem just using its regular filesystem path, so it can be much bigger than a few bytes or KB.

So, every next step in the boot loader becomes bigger and more functional, and also based on the type of partition filesystem it decides which file to load.

[root@izhar ~] ls -lh /boot/grub | grep 1_5

Stage 2: Specifies the things that GRUB can do like

  • Kernel/OS choice
  • Boot parameters
  • Boot Menu
  • Pre-boot command line

GRUB config file


[root@izhar ~] ls -l /boot/grub
[root@izhar ~] vim /boot/grub/grub.conf

Understanding Paramters in grub.conf file

  • default=0, means unless the boot process is interrupted and tell the grub otherwise it will load the first operating system
  • timeout=10, the time duration to which the user can interrupt the boot process.
  • splashimage=(hd0, 2) /grub/splash.xpm.gz, not much important but maybe for branding.
  • hiddenmenu, hides the menu choices unless the user presses the key.
  • Next, the three lines are important for operating system specific
    • title: You can give any name
    • root: This allows to specify the root directory grub the value store is in brackets as (hd0,2), hd means harddisk, then the number which is the device number as per the bios, 0 being the first device on the system, then after comma the number specifies partition number. Note: GRUB can also carry out operations without caring about partition.
    • kernel: this is very we specify the location of kernel plus any boot-time parameters that we want. vmlinuz is a kernel image vm is virtual memory which tells that system supported virtual memory and z in last tells the image is a compressed image which keeps it small the program is written in C with some machine code and stored on our system as a compressed image called vmlinuz, ro read-only and later on boot process it will be remounted as read/write, root=/path, then we other options as rd_NO_LUKS, KEYBOARD=pc, other parameters also, SYSFONT=latarcyrheb.. which tells the amount of memory to be reserved for kdump, rhgb quiet is also important parameters which is generally to see boot messages.
    • initrd: important for Linux OS, which is the initial RAM disk. This disk is loaded with drivers and modules and the likes that the kernel needs to keep the boot process ticking along. Because the kernel is small and doesn't contain all kinds of drivers for every kind of disk. So, this initrd file is loaded into memory as temporary root filesystem, hence the name RAM disk, and then the kernel uses it to access and load module that needs to do other things at the boot process. Note, initramfs is an improved form of initrd nowadays which is basically a block image loaded into memory.

init - Short for initialization or initializer

  • init is both startup manager and a session manager
  • As a startup manager it runs start-up scripts, initializes user-space, creates user-space process.
  • As a session Manager, it maintains system runlevels, manages user-spaces processes.
  • It has a special process id of 1 or PID 1
UID         PID         PPID        CMD
root        1           0           /sbin/init


                     + init (PID 1)
         ____________|______________________
        |           |           |           |    
        |- login    |- sshd     |- crond    
        |- bash     |- bash
                    |- ps

[root@izhar ~] ps -ef | less
  • User-space process forked from init have PID number above 1000
  • Kernel threads tend to have process number PID less than 1000

inittab file

  • vim /etc/inittab the line as- id:3:initdefault:
  • This line tells that the system default runlevel is 3 -->

rc.sysinit file

  • hostname
  • environment path
  • system clock initialization
  • creating /procfs, /sysfs..
  • mounting filesystems
  • swapping
  • This file is just a basic shell script:
[root@izhar ~] vim /etc/rc.d/rc.sysinit

Default Runlevel

  • 0: /etc/rc.d/rc0.d
  • 1: /etc/rc.d/rc1.d
  • 2: /etc/rc.d/rc2.d
  • 3: /etc/rc.d/rc3.d
  • 4: /etc/rc.d/rc4.d
  • 5: /etc/rc.d/rc5.d
  • 6: /etc/rc.d/rc6.d
[root@izhar ~] ls -l /etc/rc.d
[root@izhar ~] ls -l /etc/rc.d/rc3.d
This will list all shell scripts that need to be run at that run-level

[root@izhar ~] ls -l /etc/rc.d | less

Note: The script starts with either 'S' or 'K' which stands for Kill and Start script, scripts are executed in alphabetical order which means Kill scripts will run before the start scripts. The script name also has numbers which also determines the order in which the script executes. And these scripts are linked to the main files in init.d

rc.local is the last file run by init which basically checks for configuration.

Runlevels in Linux

  • Runlevel 0- system shutdown
  • Runlevel 1- No Multi-user, No Networking, No GUI. This is for troubleshooting
  • Runlevel 2- Unused
  • Runlevel 3- Multi-user, Networking, No GUI. This is common on servers
  • Runlevel 4- Unused
  • Runlevel 5- Multi-user, Networking, No GUI. This is common on desktops
  • Runlevel 6- system reboot
[root@izhar ~] runlevel
N 3

Changing Runlevel

  • first position of output denotes the previous runlevel
  • N denotes generally no runlevel detected or not changed to any runlevel
  • Second number tells the current runlevel
[root@izhar ~] telinit 5
[root@izhar ~] runlevel

[root@izhar ~] telinit 6

Note: we can also use the init command to do the same

Enabling Single User Mode

During boot time edit the parameters rhgb quiet and add one next to quiet:

rhgb quiet 1

Note: /etc/init/rc.conf will show a entry as exec /etc/rc.d/rc $RUNLEVEL which is different from rc.conf so don't be confused. This file /etc/rc.d/rc is like a master control file that guided and symlinks to the file when we reboot the system or change the runlevel

[root@izhar ~]  cat /etc/init/rc.conf
[root@izhar ~] ls -l /etc/init

Troubleshooting the Linux Boot Process

Troubleshooting the BIOS During boot time if you get the output as Operating System not found. Then power cycle the system press the F2 then select the boot option and choose a hard drive for starting the system which is basically 0 if not found you need to attach the hard drive.

Troubleshooting GRUB bootloader If you are prompted to the grub command line, first look at the grub.conf file.

grub> cat /grub/grub.conf
Error 15: File not found

If not found either boot to rescue CD and recreate or reinstall it or boot into a shell and do a manual recovery. That require path specification, refer to doc for good implementation.

grub> kernel /vmlinuz-<press_tab_for_auto_complete> root=/dev/mapper/vg_abc-lv_xyz init=/bin/bash

Now telling to find the initial RAM disk

grub> initrd /initramfs*.img
grub> boot

Now you will get a bash shell which will be in read-only mode

[bash-4.1] 
[bash-4.1] ls -l /boot
total 0
[bash-4.1] mount
Will get mounted details

[bash-4.1] mount -o remount, rw /
[bash-4.1] mount
[bash-4.1] cat /etc/fstab
[bash-4.1] mount -a
[bash-4.1] ls -l /boot
[bash-4.1] ls -l /boot/grub
[bash-4.1] cat /boot/grub/grub.old
[bash-4.1] cp /boot/grub/grub.old /boot/grub/grub.conf

Single-User Mode During boot edit the process and add 1 after rhgb quiet and the continue boot.

rhgb quiet 1

You will be prompted to Single User Mode

[root@izhar /] ping 8.8.8.8
[root@izhar /] service --status-all | less
[root@izhar /] ls /etc/rc.d/rc1.d | grep S
[root@izhar /] exit

There are many other troubleshooting options but I discuss some basic and mostly occurred issues. The other troubleshooting issues can also be found related to the kernel and init process.

Thank you for Reading!