In the Beginning

With any luck, system startup is something that administrators can ignore under normal circumstances. Most of the time the system boots automatically without the need for any human intervention. Of course, once in a while there will be a problem, and someone will have to address whatever glitch has arisen in order to successfully bring the system up.

With any luck, system startup is something that administrators can ignore under normal circumstances. Most of the time the system boots automatically without the need for any human intervention. Of course, once in a while there will be a problem, and someone will have to address whatever glitch has arisen in order to successfully bring the system up.

Booting problems invariably occur at the least convenient time. Accordingly, a thorough understanding of the normal boot process is essential in order to quickly figure out what has gone wrong and to determine what needs to be done to fix it. This column will introduce you to all of the details of the Linux boot process, hopefully preparing you for these exigencies.

Boot Sequence Overview

We will begin our discussion at the highest-level view of the process. On an Intel-based system, booting involves the following steps:

  • Check that the hardware is working properly when power is first applied to the system. These power-on self tests (POST) really only verify that the expected hardware is present and minimally functional. They happen automatically without any administrator intervention required.
  • Locate and start the boot loader program. The system BIOS looks in the Master Boot Record (a special reserved area at the beginning of the system disk for the boot loader program) and starts it executing. On Linux systems this program is usually LILO, although sometimes either the standard DOS boot loader or a different boot loader will be used.
  • Next, the boot loader runs. It is responsible for locating and initiating the actual operating system. With a DOS boot loader in use, this process is quite simple. This boot loader locates the first active partition on the system disk and loads the operating system that it finds there.

When the boot loader is LILO, a menu of boot choices is typically presented to the user. Once one of them has been selected, either by an explicit user response or the automatic selection of the default choice after a timeout period, LILO will start the operating system that resides in the disk partition corresponding to that choice.

  • Once the kernel of the operating system has been started it takes over the boot process and completes the initialization tasks necessary to make the system available to users. This will involve preparing system devices, starting server processes, initializing network connections, and a variety of similar items.

The same processes occur during the boot cycle when a system reboots, with the exception of the initial hardware testing.

Kernel Initialization and Device Probing

We took a detailed look at LILO in a previous Guru Guidance column (December 1999; available at http://www.linux-mag.com/1999-12/guru_01. html). Here, we will examine the boot process after LILO has initialized and started the Linux kernel.

During the initial phase, the kernel once again checks the system hardware and attempts to identify the specific devices that are present on the system. This process naturally varies quite a bit from system to system. On a typical system of mine, it proceeds like this:

  • First, all of the essential devices are probed: the CPU, console, and memory. Figure One contains some of the messages that are generated as a result.

Figure One: Probing for Devices

Linux version 2.2.14 (root@Pentium.suse.de) (gcc version 2.95.2 19991024
(release)) #1 Fri Mar 17 11:59:50 GMT 2000
Detected 585336240 Hz processor.
Console: colour VGA+ 80×25
Calibrating delay loop… 973.21 BogoMIPS
Memory: 78892k/81920k available (1416k kernel code, 416k reserved, 1132k
data, 64k init, 0k bigmem)
Dentry hash table entries: 16384 (order 5, 128k)
Buffer cache hash table entries: 131072 (order 7, 512k)
Page cache hash table entries: 32768 (order 5, 128k)
CPU: Intel Pentium III (Coppermine) stepping 01
Checking 386/387 coupling… OK, FPU using exception 16 error reporting.
Checking ‘hlt’ instruction… OK.
POSIX conformance testing by UNIFIX

Note that the kernel provides an approximate CPU clock speed and checks other aspects of the CPU’s functionality. The total amount of memory present on the system and the sizes of several key kernel data structures are also displayed at this time.

  • As a boot process continues, the kernel will similarly examine other hardware subsystems: I/O buses, network interfaces, hard disks, CD-ROM drives, floppy drives, other attached storage devices, and so on. As it does so, it will also initialize internal data structures and perform other related actions as they are required.
  • This initial phase of the boot process ends with the kernel initializing facilities that are related to filesystems. On the sample system, this includes initializing the logical volume manager (LVM) subsystem, enabling RAID device support and activating any configured devices (if appropriate), searching for any SCSI devices, and locating hard disk partitions.

Once all of this is complete, the kernel mounts the root filesystem read- only, frees some memory that it no longer needs, and starts the first process on the system, which runs the init program. This part of the boot process looks a lot like what you’ll see in Figure Two.

Figure Two: Initializing Facilities

LVM version 0.8e by Heinz Mauelshagen (4/1/2000)
lvm — Driver successfully initialized
md driver 0.36.6 MAX_MD_DEV=4, MAX_REAL=8
linear personality registered
raid0 personality registered
raid1 personality registered
raid5 personality registered
scsi : 0 hosts.
scsi : detected total.
Partition check:
hda: hda1 hda2 hda3
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 64k freed
INIT: version 2.78 booting
Running /sbin/init.d/boot

The messages from this phase of the boot process are later saved to the file /var/log/boot.log. They may also be viewed by running the dmesg command (you’ll probably want to pipe the output into more, unless you can read about a 1,000 words a second).

Init Takes Over

On Linux (and other Unix systems) the init process is always the first one started at boot time, and it accordingly has the process ID of 1. Once the system is running, init’s primary role is to create processes as required. However, when the program itself first starts up, it performs the actions specified in its configuration file, /etc/inittab. Since init is the first process to be started, the contents of this file specify system startup procedures. init’s functioning is structured around a series of defined system states known as run levels. A run level consists of a specific system operating mode and a predefined set of system processes; run levels are designated by a single character (usually a number). Linux systems define run levels as outlined in Table One.

Table One: Run Level Meaning and Usage

0 Halted system (ready for powering off)

1 Conversion to/preparation for single user mode

S,s Single user mode

2 Non-networked multiuser mode

3 Networked multiuser mode

4 Networked multiuser mode with graphical login

5,7-9 Undefined modes (may be defined locally)

6 Reboot mode

U,u Init process re-execution (pseudo run level)

Q,q Force reread of configuration file (pseudo run level)

a,b,c On-demand process initialization pseudo run levels

In general, init begins by taking the system to its default run level (usually 2 or 3). Later, init may be directed to change the system run levels via the telinit command, which takes the desired new run level as its argument. For example, the command:

telinit 3

says to place the system in run level 3, the command:

telinit S

says to take the system to single user mode, and the command:

telinit 6

says to reboot the system (ending up in its default run level). Whenever init changes the system run level, it follows the procedure defined in its configuration file, to which we will now turn.

The inittab file consists of a series of entries corresponding to processes to be started when the system enters each of the defined run levels. Each entry has the following syntax:


The first field, xx, is a label for the entry (typically one or two characters in length). These labels are case-sensitive and must be unique within the inittab file. The second field, levels, is a list of run levels to which the entry applies (with a blank field indicating all run levels). action is a keyword indicating how and under what conditions init should start the process specified in the entry’s final field. These are the most important action keywords:

wait: Start the process and wait for it to finish before going onto the next entry.

once: Start the process only if it is not already running (don’t wait).

respawn: Start the process (don’t wait) and automatically re-start it if the process later dies.

bootwait: Execute the process only at boot time, waiting for it to finish.

initdefault: Specifies default run level.

ctrlaltdel: Execute the action when the Ctrl-Alt-Del key sequence is detected.

power*: Several keywords are defined for various power failure-related events (see examples below).

The comment character used for the inittab file is the number sign (#), and such lines are accordingly ignored.

A Closer Look at inittab

We will now consider some entries from a typical inittab file. The file generally begins with lines similar to those in Figure Three.

Figure Three: Sample inittab File – Part I

# /etc/inittab

# default runlevel

# first script to be executed if not booting in emergency (-b) mode

The first entry defines the default run level on the system, run level 2. The second entry specifies a script for init to execute whenever the system boots. On this SuSE Linux system, the script is named boot; on Red Hat Linux systems it is often called rc.sysinit. We will take a look at the script in a future column.

Figure Four shows the next section of the inittab file, which generally specifies the controlling script used for each defined system run level.

Figure Four: Sample inittab File – Part II

# /sbin/init.d/rc takes care of runlevel handling
l0:0:wait:/sbin/init.d/rc 0
l1:1:wait:/sbin/init.d/rc 1
l2:2:wait:/sbin/init.d/rc 2
l3:3:wait:/sbin/init.d/rc 3
l4:4:wait:/sbin/init.d/rc 4
#l5:5:wait:/sbin/init.d/rc 5
l6:6:wait:/sbin/init.d/rc 6

# what to do in single-user mode
ls:S:wait:/sbin/init.d/rc S

# what to do when CTRL-ALT-DEL is pressed
ca::ctrlaltdel:/sbin/shutdown -r -t 4 now

The first section in Figure Four sets up the main entry for each of the numeric run levels. In all cases, the script named rc is run, with the target run level specified in its argument. The script performs all of the work required to initialize each run level, and isolating these tasks in this way allows the inittab file to remain uncluttered and easy to read. Note that on this system, the same structure has been set up for run level 5, but the entry itself has been commented out, leaving the run level undefined.

The two subsequent entries define actions to be taken when entering single user mode. First the rc script is again run with S as its argument. Once it completes, the sulogin program is run, which allows the root user to login at the system console/controlling terminal.

The final entry in this section of the file causes the indicated shutdown command to run whenever an authorized user enters the Ctrl-Alt-Del key sequence. The command’s options indicate that the shutdown process will commence immediately — processes will have four seconds to exit gracefully after receiving the termination signal before they are killed — and the system will then be rebooted.

Remaining entries in our sample inittab file concern system power failures and terminal processes and look like those in Figure Five.

Figure Five: Sample inittab File – Part III

# what to do when power fails/returns
pf::powerwait:/sbin/init.d/powerfail start
pn::powerfailnow:/sbin/init.d/powerfail now
po::powerokwait:/sbin/init.d/powerfail stop

# getty-programs for the normal runlevels

# The “id” field MUST be the same as the last

# characters of the device (after “tty”).
1:1234:respawn:/sbin/mingetty –noclear tty1
2:1234:respawn:/sbin/mingetty tty2
3:1234:respawn:/sbin/mingetty tty3

The first three entries all call the same script, powerfail, with various arguments; they will cause an automatic system shutdown to begin, happen immediately, or be terminated (respectively). Note that these entries applied to all system run levels.

The final three entries of the file correspond to getty processes for three terminal lines (the actual program is named mingetty), enabling them to be used for user logins. These entries are relevant to run levels 1 through 4, and init will automatically restart any getty process that is terminated.

More to Come

So booting your system actually occurs in three stages; first the kernel is loaded, next the init process is started, and finally the system boot scripts are run.

Unfortunately, since we’re out of space for this month, we will have to walk through the boot scripts next time. See you in a month.

Æleen Frisch is the author of Essential System Administration. She can be reached at aefrisch@lorentzian.com.

Comments are closed.