System startup and boot processes
Let's break the Linux boot process into nine steps that occur in almost every Linux configuration:
- Hardware/firmware: The BIOS or firmware system reads the master boot record on the harddisk or other boot device (for example, CD, floppy, netboot, etc.).
- A boot loader runs. Linux systems on x86 systems typically use LILO or GRUB. Some older systems might use loadlin to boot via an intermediate DOS partition. On Power PC® systems, this might be BootX or yaboot. In general, a boot loader is a simple program that knows where to look for the Linux kernel, perhaps choosing among several versions or even selecting other operating systems on the same machine.
- The kernel loads.
- The root filesystem is mounted. In some cases, a temporary ramdisk image is loaded before the true root filesystem to enable special drivers or modules that might be necessary for the true root filesystem.
One we have a root filesystem in place, we are ready for initialization proper.
- Start the process
init, the parent of all other Linux processes.
- Read the contents of /etc/inittab to configure the remaining boot steps. Of special importance is the line in /etc/inittab that controls the runlevel the system will boot to (and therefore which further steps will be taken during initialization).
Actually, everything after this point is completely controlled by the content of the file /etc/inittab. Specifically, the scripts and tools that run generally follow some conventions, but in theory you could completely change /etc/inittab to run different scripts.
One specific setting in /etc/inittab is particularly crucial. A line similar to:
generally occurs near the top of the file, and sets the runlevel. This runlevel controls what actions are taken in the remainder on the /etc/inittab script.
Just what happens as an /etc/inittab script is processed? And specifically, what conventional files and directories are involved in the process?
- Runlevel-neutral system initialization. Generally there are some initialization actions that are performed regardless of runlevel. These steps are indicated in /etc/inittab with a line like:
# System initialization.
On some Linux systems (mostly Debian-based systems), you will see something more like:
If the latter case, /etc/init.d/rcS is a script that simply runs each of the scripts matching /etc/rcS.d/[Ss]??*. On the other hand, if your system uses /etc/rc.d/rc.sysinit, that file contains a single long script to perform all the initialization.
- Runlevel-specific system initialization. You may actually define as many actions as you like related to runlevel, and each action may pertain to one or more runlevels. As a rule, /etc/inittab will contain some lines like:
In turn, the script /etc/rc.d/rc will run all the files matched by the pattern /etc/rc$1.d/[KkSs]??*. For example, on the sample system described that starts at runlevel 5, we would run (in order):
The files(s) starting with "K" or "k" are kill scripts that end processes or clean up their actions. Those starting with "S" or "s" are startup scripts that generally launch new processes or otherwise prepare the system to run at that runlevel. Most of these files will be shell scripts, and most will be links (often to files in /etc/init.d/).
Most of the time, once a Linux system is running at a runlevel, you want to log into the system as a user. To let that happen, a program called getty runs to handle the login process. A number of variations on the basic getty are used by distribution creators, such as agetty, mgetty, and mingetty. All do basically the same thing.
- Log in at the prompt. Our good friend /etc/inittab usually launches getty programs on one or more virtual terminals and does so for several different runlevels. Those are configured with lines like:
# Run gettys in standard runlevels
The first number reminds us of the virtual terminal where the getty runs; the next set of numbers are the several runlevels where this will happen (for example, launching mingetty in all of the runlevels 2, 3, 4, and 5).
Next steps might involve launching additional services, logging into a graphical environment, restoring UI settings, or other more personalized details that are outside the scope of this tutorial.
The concept of runlevel is somewhat arbitrary, or at least it is not hardcoded into a Linux kernel. Valid runlevel numbers to set with the
initdefault option (or override otherwise) are 0 - 6. By convention, the following meanings are given to each number:
Listing 1. Runlevels, defined
# Default runlevel. The runlevels used by Mandrake Linux are: # 0 - Halt (Do NOT set initdefault to this) # 1 - Single user mode # 2 - Multiuser, without NFS (The same as 3, if you don't have networking) # 3 - Full multiuser mode # 4 - Unused # 5 - X11 # 6 - Reboot (Do NOT set initdefault to this)
This convention, as you can see, is as used in the Mandrake Linux distribution, but most distributions obey the same convention. Text-only or embedded distributions may not use some of the levels, but will still reserve those numbers.
You have seen a number of /etc/inittab lines in examples, but it is worth understanding explicitly what these lines do. Each one has the format:
id field is a short abbreviation naming the configuration line (1 - 4 characters in recent versions of
init; 1 - 2 in ancient ones). The
runlevels is explained already. Next is the action taken by the line. Some actions are "special," such as:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
This action traps the Ctrl-Alt-Delete key sequence (regardless of runlevel). But most actions simply relate to spawning. A partial list of actions includes:
respawn: The process will be restarted whenever it terminates (as with getty).
wait: The process will be started once when the specified runlevel is entered, and
initwill wait for its termination.
once: The process will be executed once when the specified runlevel is entered.
boot: The process will be executed during system boot (but after sysinit). The runlevels field is ignored.