Sunday, May 07, 2006

Linux's boot process explained

Short history of the UNIX operating system

Linux is an implementation of the UNIX operating system concept. UNIX was derived from AT&T's "Sys V" (System 5). The initialization process is meant to control the starting and ending of services and/or daemons in a system, and permits different start-up configurations on different execution levels ("run levels").
Some Linux distribution, like SlackWare, use the BSD init system, developed at the University of California, Berkeley.
Sys V uses a much more complex set of command files and directives to determine which services are available at different levels of execution, than the BSD's do.

Booting the Linux operating system

The first thing a computer does on start-up is a primer test (POST - Power On Self Test). This way several devices are tested, including the processor, memory, graphics card and the keyboard. Here is tested the boot medium (hard disk, floppy unit, CD-ROMs). After POST, the loader from a ROM loads the boot sector, which in turn loads the operating system from the active partition.
The boot blocks is always at the same place: track 0, cylinder 0, head 0 of the device from which we're booting. This block contains a program called loader, which in Linux's case is LiLo (Linux Loader), or Grub (GNU Grub Unified Boot Loader), which actually boots the operating system. These loaders in Linux , in case of a multi-boot configuration (more operating systems on a computer), permit the selection of the operating system to be booted. Lilo and Grub are installed or at the MBR (Master Boot Record), or at the first sector of the active partition.
In the following we will refer to LiLO as boot loader. This is usually installed in the boot sector, also known as MBR. If the user decides to boot Linux, LiLo will try to load the kernel. Now I will present step-by-step LiLo's attempt to load the operating system.

1. In case of a multi-boot config, LiLo permits the user two choose an operating system from the menu. The LiLo settings are stored at /etc/lilo.conf. System administrators use this file for a very detailed finement of the loader. Here can be manually set what operating systems are installed, as well as the method for loading any of them. If on the computer there is only Linux, LiLo can be set to load directly the kernel, and skip the selection menu.

2. The Linux kernel is compressed, and contains a small bit, which will decompress it. Immediately after the first step begins the decompression and the loading of the kernel.

3. If the kernel detects that your graphics card supports more complex text modes, Linux allows the usage of them - this can be specified or during the recompilation of the kernel, or right inside Lilo, or other program, like rdev.

4. The kernel verifies hardware configuration (floppy drive, hard disk, network adapters, etc) and configures the drivers for the system. During this operation, several informative messages are shown to the user.

5. The kernel tries to mount the file system and the system files. The location of system files is configurable during recompilation, or with other programs - LiLo and rdev. The file system type is automatically detected. The most used file systems on Linux are ext2 and ext3. If the mount fails, a so-called kernel panic will occur, and the system will "freeze".
System files are usually mounted in read-only mode, to permit a verification of them during the mount. This verification isn't indicated if the files were mounted in read-write mode.

6. After these steps, the kernel will start init, which will become process number 1, and will start the rest of the system.

The init process

It's Linux's first process, and parent of all the other processes. This process is the first running process on any Linux/UNIX system, and is started directly by the kernel. It is what loads the rest of the system, and always has a PID of 1.

The initialization files in /etc/inittab

First time the initialization process (init) examines the file /etc/inittab to determine what processes have to be launched after. This file provides init information on runlevels, and on what process should be launched on each runlevel.
After that, init looks up the first line with a sysinit (system initialization) action and executes the specified command file, in this case /etc/rc.d/rc.sysinit. After the execution of the scripts in /etc/rc.d/rc.sysinit, init starts to launch the processes associated with the initial runlevel.
The next few lines in /etc/inittab are specific to the different execution (run-) levels. Every line runs as a single script (/etc/rc.d/rc), which has a number from 1 to 6 as argument to specify the runlevel.
The most used action in /etc/inittab is wait, which means init executes the command file for a specified runlevel, and then waits until that level is terminated.

The files in /etc/rc.d/rc.sysinit

The commands defined in /etc/inittab are executed only once, by the init process, every time when the operating system boots. Usually these scripts are running as a succession of commands, and usually realise the following:

1. Determine whether the system takes part of a network, depending on the content of /etc/sysconfig/network

2. Mount /proc, the file system used in Linux to determine the state of the diverse processes.

3. Set the system time in fuction to the BIOS settings, as well as realises other settings (setting of time zone, etc), stabilized and configured during the installation of the system.

4. Enables virtual memory, activating and mounting the swap partition, specified in /etc/fstab (File System Table)

5. Sets the host name for the network and system wide authentication, like NIS (Network Information Service), NIS+ (an improved version of NIS), and so on.

6. Verifies the root fily system, and if no problems, mounts it.

7. Verifies the other file systems specified in /etc/fstab.

8. Identifies, if case of, special routines used by the operating system to recognize installed hardware to configure Plug'n'Play devices, and to activate other prime devices, like the sound card, for example.

9. Verifies the state of special disk devices, like RAID (Redundant Array of Inexpensive Disks)

10. Mounts all the specified file systems in /etc/fstab.

11. Executes other system-specific tasks.

The /etc/rc.d/init.d directory

The directory /etc/rc.d/init.d contains all the commands which start or stop services which are associated with all the execution levels.
All the files in /etc/rc.d/init.d have a short name which describes the services to which they're associated. For example, /etc/rc.d/init.d/amd starts and stops the auto mount daemon, which mounts the NFS host and devices anytime when needed.

The login process

After the init process executes all the commands, files and scripts, the last few processes are the /sbin/mingetty ones, which shows the banner and log-in message of the distribution you have installed. The system is loaded and prepared so the user could log in.

Linux's execution levels

The execution levels represent the mode in which the computer operates. They are defined by a set of available services at any time they are started. The execution levels represent different ways Linux uses to be available to you, the user, or eventually the administrator.
As daily user you don't have to bother with the execution levels, although the multi-user level makes the services which you need while using Linux in a network (though in a transparent mode) available.
In the next few sentences I'll present the execution levels, one by one:

0: Halt (stops all running processes and executes shutdown)

1: Known under the name "Single-user mode". In this case the system runs with a reduced set of services and daemons. The root file system is mounted read-only. This runlevel is used when the others fail while booting.

2: On this level run the most of the services, with the exception of network services (httpd, named, nfs, etc). This execution level is ideal for the debug of network services, keeping the file system shared.

3: Complete multi-user mode, with network support enabled.

4: Unused, in most of the distributions. In Slackware this level is equivalent with 3, the only difference is that this has graphic login enabled.

5: Complete multi-user mode, with network and graphic subsystem support enabled.

6: Reboot. Stops all running processes and reboots the system to the initial execution level.

Modification of execution levels

The most used facility of init, and maybe the most confusing one, is the ability to move from an execution level to an other.
The system boots into a runlevel specified in /etc/inittab, or to a level specified at the LiLo prompt. To change the execution level, use the command init. For example, to change the execution level to 3, type
init 3

This stops most of the processes and takes the system into a multi-user mode with networking enabled. Attention, changing the init level might force several daemons used at the moment to stop!

The directories of execution levels

Every execution level has a directory with a symbolic links (symlinks) pointing to the corresponding scripts in /etc/rc.d/init.d. These directories are:

/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d

The name of the symlinks are semnificative. It specifies which service has to be stopped, started and when. The links starting with an "S" are programmed to start in various execution levels. The links also have a number in their name (01-99). Now some examples of symlinks in the directory /etc/rc.d/rc2.d:

K20nfs -> ../init.d/nfs
K50inet -> ../init.d/inet
S60lpd -> ../init.d/lpd
S80sendmail -> ../init.d/sendmail

When operating systems change the execution level, init compares the list of the terminated processes (links which start with "K") from the directory of the current execution level with the list of processes which have to be started (starting with "S"), found in the destination directory.

Example:

When the system boots into runlevel 3, will execute all the corresponding links starting with "S", in an order accorind to their number:

/etc/rc.d/rc3.d/S60lpd start
/etc/rc.d/rc3.d/S80sendmail start
(and so on)

If the system now changes to runlevel 1, will execute:

/etc/rc.d/rc3.d/K20nfs stop
/etc/rc.d/rc3.d/K50inet stop
(presuming that nfs and inet are NOT in /etc/rc.d/rc1.d)

After that it will start all the processes mentioned in /etc/rc.d/rc1.d except which are already running. In this example there's a single one only:

/etc/rc.d/rc1.d/S00single

Changing the current execution level

To change the current execution level for example to level 3, edit /etc/inittab in a text editor, and edit the following line:

id:3:initdefault:

(do not change the initial runlevel to 0 or 6!)

Booting into an alternative execution level

At the LiLo prompt you have to write the number of the wanted execution level, before booting the operating system. This way to boot into the third level, type for example:

linux 3


Eliminating a service from an execution level

To disable a service from a runlevel, you might simply delete or modify the corresponding symlink.
For example, to disable pcmcia, and don't start in the future, type:

rm /etc/rc.d/rc3.d/S45pcmcia


Adding a service to an execution level

To add a service, it is needed to create a symlink pointing to the corresponding scripts in /etc/rc.d/init.d. After the symlink is created, be sure to assign it a number, so it would be started in the right time:

To add "lpd" to runlevel 3, type:

ln -s /etc/rc.d/init.d/lpd /etc/rc.d/rc3.d/S64lpd




P.S.: This article has been originally written by Ovidiu T. He gave me the permission to translate and publish it, and since I found the article interesting, I did that way as well, although I don't treat myself responsible about the content of it.

46 comments:

Anonymous said...

What does "disponible" mean? It's not an English word.

Anonymous said...

nice article, good job dude

Anonymous said...

thanks for the info!

cruocitae said...

disponible == available

Sorry for the mistake, I'll correct it immediately.

Anonymous said...

I don't see where it mentions which distribution was used as the basis. But the run levels shown appear to be for Red Hat or SuSE based systems. This is by no means set in stone. Only runlevels 0, 1/S, and 6 are standardized. For example, Debian runlevels 2, 3, 4, and 5 are identical (to Red Hat runlevel 5) unless the system administrator changes them. Runlevel 2 is the default on Debian based systems.

Slackware doesn't quite use the BSD init system but it is very similar in layout. Slackware also supports SysV init scripts in addition to its preferred BSD-like init scripts.

cruocitae said...

The "victim" is Fedora 4.. I think documenting it will gain a larger audience, since (according to stats), Fedora has a bigger userbase than for example Debian (although I prefer the latter distro).. If you'd like to write some words on Debian's boot process and runlevels.. be my guest!

Anonymous said...

A very nice and informative article.

Anonymous said...

excellent post. Keep up those informative posts coming

Anonymous said...

Well done, good article.

Anonymous said...

You might want to run the article through a spell checker as there are quite a few typos. There are also some factual errors, e.g. the init process is process 1, not process 0.

cruocitae said...

Typos corrected using SpellCheck.net.. I'm not sure how good it is, it was google's first match.. I found several "excution levels", and a "storead" among others.

Anonymous said...

Quite an interesting note about Linux system. I have not gone so deep into Linux /etc files myself. However, good to show that it is well-documented.

Anonymous said...

Horrible, most of the process you described is distro dependent, some distros don't even use rc scripts to init services, go check your facts.

cruocitae said...

1.) I don't know what "most distros" are you talking about..
2.) As I've said before, I think it's more ideal to make a description of one of the most known distros, than one of a noname. Fedora/RH is also a base of several other distributions.. I don't know much about slack's init system, but all the other major distros use Sys V style init as default.
3.) Please do not comment "most distros/ppl use grub nowadays".. LiLo was the original loader, and IT is what best fits Linux even these days.

Anonymous said...

"semnificative" is not an English word, although I wish it was!

Anonymous said...

You have not used Linux if you haven't gone into /etc.

Anonymous said...

"3.) Please do not comment "most distros/ppl use grub nowadays".. LiLo was the original loader, and IT is what best fits Linux even these days."

Completely a false statement. If you're using RH/Fedora as the basis for your article, the default loader is GRUB, and has been for many many years (I think since RH 7.2?). Your choice of LiLO to write this article is actually the non-standard path of travel and does the reader a disservice.

Unknown said...

Thank you for the informative read. However, I have been scratching my head about one thing:

How do you remove LiLO from the MBR? I know that there are ways to do it with floppy discs, but since I'm using a laptop, I'm looking for other ways.

I want to remove linux from my laptop's HDD but I can't do that without first restoring the original MBR. If you know of a way, I would greatly appreciate it.

James

Anonymous said...

permits the user two choose

I think you meant

permits the user to choose

cruocitae said...

Bah, I didn't say it is the currently most used boot loader.. I said it is the boot loader originally written for linux, and which best fits with Linux.
It's another tale that today's distros use GRUB..
Anyways, the target of this article was explaining how runlevels work, and basically LiLo isn't the "main person", and the things go almost the same way with grub as well..

Anonymous said...

Great, now we see some life ;)) Anyway, still waiting for suse 10.1 review :P

Anonymous said...

"UNIX was derived from AT&T's "Sys V" (System 5)."

Erm... no. System 5 was a UNIX system, as in UNIX came before System 5 :P

Anyhow, nice article - esp. for newbies, even my friend understood it.

Anonymous said...

How can LILO access /etc/lilo.conf if the kernel which mounts the filesystem hasn't loaded yet?
Or am I just misunderstanding everything/something?

Anonymous said...

The previous anonymous asked how does lilo loads lilo.conf when the kernel (or filesystem) isn't loaded yet. To my understanding lilo.conf is not accessed during the boot process. When an admin changes the lilo.conf, he/she will have to run the lilo (with the -C option). When this is done, lilo writes the information to the boot sector.

Anonymous said...

about the lilo.conf question above:
lilo.conf is read by the lilo "installer", which writes the lilo "bootloader" into the mbr.

about the original article:
a general "thanks" for that article. typos and other problems with facts and detailes about the distro were already stated. you should consider updating it with the information given in the comments to make it more precise. just _say_ it is about fedora if it is, then noone can say anything agains the facts given.

Anonymous said...

Gracias por el articulo, muy interesante, tienes las version en espanol?
Thank you very much. It is very interesting. Do you have the spanish version?

sebelk said...

"How can LILO access /etc/lilo.conf if the kernel which mounts the filesystem hasn't loaded yet?
Or am I just misunderstanding everything/something?"

LILO doesn't access /etc/lilo.conf, but it does to what is saved in MBR, because of this, you need to reinstall LILO each time you modify /etc/lilo.conf. LILO is "filesystem-blind".

cruocitae said...

Somebody requested a more in-depth explanation, and I researched for it as well.

http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO-1.html

This really explains what is going on.. go, read! :>

Anonymous said...

lovely post.
keep it up man!

Anonymous said...

Thank You for an awesome article. I do have one question. I've attempted to install Slack on server using RAID, and it cannot install LILO or GRUB to the MBR. If you're using a RAID, where do you install the bootloader?
Thanks!

Anonymous said...

"semnificative" is not an English word, although I wish it was!

So what does this word mean?

Anonymous said...

While I found the article somewhat painful to read because of some odd wording and spelling, it was, overall, a very informative piece. Thanks!

Anonymous said...

"things go almost the same way with grub as well."

Just how *do* you specify the runlevel at boot time in grub? I've got one machine that uses grub, and I can't get lilo to work on it (probably RAID trouble).

Anonymous said...

Thank you for the well written informative article. This was written at exactly the right level for me, and I'm sure many others.

Cheers!

-Matt

Anonymous said...

This is a good article. I was looking for such type of documentation about boot process. It helped me to understand a lot about boot process. Thanx for this article.

Parveen Garg

Anonymous said...

excellent article....i'm tackling unnix from the ground up and this is a great place to start...thanks for putting in the time...cheers...pjh

vpsingh88 said...

Thanks a million For such a clear explanation.

This article should be on wikipedia.

Anonymous said...

Great post and thanks for writing!

Anonymous said...

simply awesome..today i had viva on LINUX OS..read this whole thing in 1 hour..got full marks!

Thanks.

Anonymous said...

Thanks a lot for this execellent article!
Joerg

Anonymous said...

Hey! This information is really great. Helps in critical situations. Great!

Unknown said...

A very nice article....
Especially for the newbies....
Infact it helped me....

I.M.Possible said...

Yes, definitely good detailed article. But you did not mention the linux distro name.

I am searching for ubuntu7.04(live cd) distro.

Mohan Karuppannan said...

I read many of the articles but those are not satisfied me. You have done Good job. Keep on posting good ARTICLES Dude.

Anonymous said...

good work!! was very useful.

Anonymous said...

Your blog is very nice