User Tools

Site Tools


handbook:handbook:booting

Biblical version:

In the beginning, there was GRUB (or maybe LILO) and GRUB loaded the kernel, and kernel begat init, and init begat rc, and rc begat network and httpd and getty, and getty begat login, and login begat shell and so on.

Introduction

In this section we will explore how most Linux distributions boot, in some detail. I haven't seem many full explanations of this, and it's not terribly complex, although it is somewhat long.

I will use a Red Hat 9 system to explain it, but most distributions should be almost the same… except Slackware and its derivatives.

While almost everyone uses what's called a SystemV init setup, Slackware and derivatives use a BSD init ( like FreeBSD, OpenBSD and *BSD, of course :-), which is different.

Step 1: The Boot Manager

The boot manager is a small program that resides mostly on the MBR 1 and presents you with a menu letting you choose what operating system (if you have more than one) you want to boot.

Nowadays the most common one is GRUB, with LILO a second popular alternative.

I will not get into much detail about them, both are well documented, and most of what you want to know about them is how to make them boot windows, or multiple linux kernels, and that's not what this article is about.

In the regular, plain-old-booting-linux business, all the boot loader does is:

Load the kernel into memory
Optionally load a ramdisk called initrd containing stuff like disk drivers
Pass the kernel arguments, of which we are only interested in runlevel and init
Start execution of the kernel.

So, what are those two arguments I mentioned, runlevel and init? We'll get to runlevel eventually, but init we'll see soon.

Step 2: init

The init argument the boot loader can pass to the kernel is the name of a program. Usually, none is given, and the default, /sbin/init is used.

You could, for example, pass init=/bin/sh to the kernel, and then a plain shell would be used instead.

What does the kernel do with init? It starts it. It's the only program the kernel itself starts, everything else is started by init.

The regular Linux init will then read a file called /etc/inittab to see what it has to do. The format of that file is somewhat involved and archaic, but it's not too complex.

To understand it, you have to know what a runlevel is. A runlevel is a state for the system. Usually, you have runlevels 0,1,2,3,4,5,6 and maybe S (Debian has it, Red Hat doesn't).

For example, runlevel 1 (or S) usually means a single shell running, as few processes as possible, maybe no login, maybe just asking for root's password. While runlevel 5 may mean 6 logins in text mode, a graphical login, and a web server running. As I said, two different states of the system.

The system starts, when init loads in an undefined state (sometimes called N), and then will switch to one runlevel or another depending on what the runlevel argument from the bootloader to the kernel was, and the contents of /etc/inittab.

For example, if the bootloader passed runlevel as 5, init will try to switch to that state. If no runlevel argument was passed, it will use its default, which is in /etc/inittab

Normally the only reason for the bootloader to pass an argument is if you want it to boot in an unusual state, for example, a single-user mode for maintenance (runlevel 1), or with a replacement init because of disk corruption (init=/bin/sh).

So, let's look at that file…

Step 2.1: /etc/inittab

They have 4 fields, separated with colons, which mean (taken from the inittab(5) man page)

id - This has no real meaning, but should be different for each line, can be one to four characters runlevels - For example, 2345 means this line applies to runlevels 2,3,4 and 5. In some actions (see below) this field is ignored, in some it means something else :-P action - what this line does process - a command to be executed. Some actions require no command

When it's booting, to decide the desired runlevel (again, if it's not passed as an argument), init will look for a line with the initdefault action.

For example:

id:5:initdefault:

That means: go to runlevel 5. So, if you wanted to change the default runlevel, that's what you change.

But what does it mean to go to one runlevel? Well, each runlevel runs a different configuration of software. One runlevel may have a webserver running, and another not have it. One runlevel may show you a graphical login screen, or not, or give you 6 text terminals, or one.

Think of it like those old multiboot menus on DOS which read different autoexec.bat and config.sys files.

The meaning of the runlevels may be different on different distributions, here's what it says for Red Hat:

The runlevels used by RHS are:
  0 - halt (Do NOT set initdefault to this)
  1 - Single user mode
  2 - Multiuser, without NFS (The same as 3, if you do not have networking)
  3 - Full multiuser mode
  4 - unused
  5 - X11
  6 - reboot (Do NOT set initdefault to this)

So, for example, if you switched to runlevel 6, it would reboot. You can switch runlevels at any moment using the telinit command, but for the purposes of booting and this article, you switch only once, to the default runlevel, and you're done.

So, what happens after you know you are going to runlevel 5?

If you are booting, you check all lines with actions sysinit boot and bootwait, in that order, and run what the command field says.

In Red Hat's default inittab, that's just this:

si::sysinit:/etc/rc.d/rc.sysinit

So, it will run a script called /etc/rc.d/rc.sysinit, which does stuff like loading a terminal font, check disks, mount stuff… basic system habitability drudge work.

Then it will get all lines with action once and wait that have the desired runlevel in the runlevel field, and will run its commands, and will wait until the wait lines commands are finished.

In Red Hat, for runlevel 5:

l5:5:wait:/etc/rc.d/rc 5

What this particular script does is start all services configured for runlevel 5. That's what you see when it says things like “configuring the frobnozz [OK]” on boot. Now, let's see the details…

Step 3: Services

In fact, services start before the end of what's described in Step 2.1, so this is no longer logically organized. Complain to Congress, not to me ;-)

When you install a decently packaged software that needs to run without being manually started by a user (think webserver), it should have provided you with a control script for itself, and placed it in the standard place: /etc/init.d/ or /etc/rc.d/init.d depending on distribution. Most have both and they are the same.

There you will find many scripts. For example, I have one called /etc/init.d/network which, amazingly enough, controls the network.

For example, if I do /etc/init.d/network stop it brings down the network. If I did /etc/init.d/network start it would bring it back up.

Some services support more or less commands, but all support stop, start and restart. You can learn what they handle by calling it without arguments:

[root@wiki root]# /etc/init.d/network
Usage: /etc/init.d/network {start|stop|restart|reload|status}
[root@wiki root]# /etc/init.d/httpd
Usage: /etc/init.d/httpd {start|stop|restart|condrestart|reload|status|fullstatus|graceful|
help|configtest}

For each runlevel, there's a list of services that should be started, and a list of services that should be stopped.

On entering runlevel 5, for example, you may want to stop service httpd but start service smb, or whatever.

I heavily recommend you use a system management tool, like Red Hat's redhat-config-services or Debian's rcconf to handle this, they are simple and work just fine.

But, if you want to do it by hand, or just want to know how that configuration is stored, read on :-)

For each runlevel N, there is a folder, called /etc/rc.d/rcN.d.

Here's part of my folder for runlevel 5:

K05saslauthd -> ../init.d/saslauthd
K10lircd -> ../init.d/lircd
K10lircmd -> ../init.d/lircmd
K15httpd -> ../init.d/httpd
K15nessusd -> ../init.d/nessusd
:
:
:
S00microcode_ctl -> ../init.d/microcode_ctl
S05kudzu -> ../init.d/kudzu
S08iptables -> ../init.d/iptables
S10network -> ../init.d/network
S12syslog -> ../init.d/syslog
S13irqbalance -> ../init.d/irqbalance
:
:
:

The things that start with K are to be stopped. Those which start with S are to be started. The numbers are to give them an order to be killed or started.

So, we start by taking all the K stuff. For each, we check if the service is running. If it is, it's stopped.

Then we go over all the S stuff, if it is not running, it's started.

The stopping or starting is simply done by calling, for example

/etc/rc.d/rc5.d/S10network start

Since S10network is a symbolic link to /etc/rc.d/init.d/network, it's just the same as what we used before to start the network service.

In Red Hat, there's one particular service called local, usually started in last place (like S99local), which runs /etc/rc.d/rc.local.

If you have something you want to run on boot, but don't want to bother creating a service script (or don't know how), you can just tack it on the end in rc.local and have it work.

However, be careful! You can't login into the system until rc.lcoal finishes, so don't put there any commands that take too long. Or if you do, put them in the background by adding a & at the end of the command.

On other distributions this will be different. For example, Debian has a folder where you throw scripts, instead of a single file.

After all that is done, all services are started, we get back to inittab.

Step 4: More inittab fun

Now init will get all lines with action respawn for the desired runlevel and start their processes. respawn commands are restarted when they end, so they will be running pretty much all the time as long as you are in this runlevel.

In Red Hat for runlevel 5:

1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
x:5:respawn:/etc/X11/prefdm -nodaemon

The lines with id 1 through 6 run a program in the terminals you reach using ALT-F1 through ALT-F6, which asks your username. Yes, those are what you use to login in text mode.

The line with id x gives you a graphical login. Notice that this is not in runlevels 1,2,3 or 4, so those have no graphical login.

You could have more or less text terminals or graphic logins editing this. Notice that to have two graphical logins you need other configurations, too.

And voilá, you are booted and ready to login.

handbook/handbook/booting.txt · Last modified: 2010/04/15 21:18 (external edit)