If you’ve never seen Linux boot, the first time you do, it’s pretty daunting. Unlike Windows, Linux displays everything it’s doing every step of the way, right up until the login prompt, weather that be an X system (GUI), or a terminal. This is extremely helpful for IT technicians and system administrators, as we can see when exactly problems arise, however for the user, it can seem somewhat unnecessary and intimidating.
This document is based around Redhat 9\Redhat Enterprise Edition, however the Linux boot process remains the same for almost all distributions out there. A note will be added before mentioning anything specific to Redhat.
This document will also go into some detail about the boot process, starting with the BIOS, and ending with the highly customizable ways in which you can boot Linux.
This document has been written for the x86 architecture.
The Very Beginning
The boot process starts with the BIOS. The BIOS lives on the motherboard of the machine, and is a read-only program. It’s the first software that runs when you switch a machine on, and initializes all the devices connected, such as processors, hard disks, floppy drives and video adapters. Once it has tested everything (to make sure it’s a complete system), it checks to see what device is bootable. Usually the first IDE disk on the primary IDE controller is set to boot first, so the BIOS looks at the first 512k, and executes whatever program happens to be there. This section of the disk is known as the MBR (Master Boot Record), and since it’s where the BIOS looks to boot, it makes sense to store an application that boots Operating systems.
The Boot Loader
This application is known as the boot loader. There are 3 main ones in existence, with almost every computer running Windows or Linux using them, they are LILO, GRUB, or NTLDR. NTLDR is of course the boot loader used by Windows. GRUB and LILO are used by Linux systems, Many (including Redhat distributions) use GRUB as there preferred choice. GRUB is more feature packed.
There is also a document detailing the use of GRUB on the serpent.co.uk here.
The boot loader is responsible for locating the kernel, and handing control over to it. From there, the Linux kernel will start the rest of the system. GRUB is also able to load other operating systems, notably Windows, however since GRUB cannot directly load the Windows Kernel, it simply hands control over to NTLDR.
The Linux Kernel and Initrd
Only now does Linux start to boot. Until now, The BIOS and the boot loader have been in control. The Kernel itself is a very basic by nature, it will not be enough for users to fully interact with Linux, so the kernel needs to load 2 support applications, initrd first, then init. initrd is responsible for creating a RAM disk, and then extracting modules\drivers for the systems hardware, it then loads these modules into memory and executes them. Once they are operational, the RAM disk is unmounted.
The actual kernel is loaded from an image file, located in the /boot directory. It takes on the filename vmlinuz-.imz. This file must remain intact in order to boot. Also, the /initrd directory must remain present, even when empty. Initrd may also be stored in an image file in the /boot directory.
Once the Kernel has loaded, and initrd has done it’s thing. The /sbin/init program loads. This is the parent process for all other processes started in Linux. It’s usually started as PID 1, and although the kernel is loaded, it will background itself to perform all low-level functions needed by any processes.
So what does init do? The first job for /sbin/init (from now on referred to as init), is to read the /etc/rc.d/rc.sysinit file to set up the user environment. This file sets variables, loads the hardware clock, checks to make sure all necessary services and processes are available and generally make sure an intact Linux system is present.
Next it loads the necessary scripts depending on the runlevels. Runlevels is a subject that usually confuses most users new to Linux. The /etc/inittab file contains information about which runlevel should be used. runlevels are states of operation, there are usually 7 runlevels, and each different runlevel has a different set of applications and services associated with it. For example, if a Linux system has been set to boot at runlevel 3 (set in the /etc/inittab file), then the system would load up, however there would only be a command shell, no GUI. This is because runlevel 3 is known as Full Multiuser mode without X11 (GUI).
However if your /etc/inittab file states the default runlevel is 5, which is the default, then you would have a fully GUI system ready and loaded.
For more information about runlevels, please see the Redhat Linux documentation here.
The runlevels break down to the following:
- 0 - Halt, The system is in an idle state, and nothing is loaded.
- 1 - Single User Mode, only a command shell is available, no other users can log in.
- 2 - Multiuser Without NFS, any amount of users can logon but not remotely. No networking.
- 3 - Full Multiuser Mode, any amount of users can login, either locally of remotely. No GUI.
- 4 - Not Used.
- 5 - X11, a GUI such as KDE or GNOME will be loaded, allowing graphical login and operation.
- 6 - Reboot, the machine will prepare for reboot.
Most of the runlevels are self explanatory, however what isn’t obvious is how and why they are used. Runlevels come in very handy for troubleshooting system problems. For example, most systems default to runlevel 5, however if there is a problem with the GNOME software, you will not be able to see a login screen on boot. It is possible to then reboot the machine, edit the
/etc/inittab file to set runlevel 1 as the default, then you will be able to boot into a working
shell, and diagnose the problem. But how does Linux know what to load for what runlevel?
It’s a surprisingly easy answer. Within the folder
/etc/rc.d are many other folders. Usually all the scripts that load\terminate when a runlevel changes are located in init.d, but there will be folders to each runlevel, rc5.d, rc3.d and rc1.d for example. Within each folder, are the scripts that would execute\terminate for that runlevel.
Each script starts with either a K or an S. Scripts with K, mean that process will be killed when switching to that runlevel, alternatively, the scripts beginning with S, mean the process will be started.
The last thing init does is execute the
/etc/rc.d/rc.local file, which allows users to customize the system. If you would like any user defined applications\scripts to execute, this is where you would store them, similar to the ‘startup’ folder in Windows!
I hope this guide helps clear up the mysteries of the Linux boot process a little. Please contact us via the feedback page if you have any comments.