Purchase  Copyright © 2002 Paul Sheer. Click here for copying permissions.  Home 

next up previous contents
Next: 32. init, ? getty, Up: rute Previous: 30. exim and sendmail   Contents

Subsections

31. lilo, initrd, and Booting

lilo stands for linux loader. LILO: is the prompt you first see after boot up, from which you can usually choose the OS you would like to boot and give certain boot options to the kernel. This chapter explains how to configure lilo and kernel boot options, and to get otherwise non-booting systems to boot.

The lilo package itself contains the files

 
 
 
/boot/boot.b      /boot/message     /sbin/lilo
/boot/chain.b     /boot/os2_d.b     /usr/bin/keytab-lilo
/usr/share/doc/lilo-<version>

which is not that interesting, except to know that the technical and user documentation is there if hard-core details are needed.

31.1 Usage

When you first start your LINUX system, the LILO: prompt, at which you can enter boot options, is displayed. Pressing Tab displays a list of things to type. The purpose is to allow the booting of different LINUX installations on the same machine, or different operating systems stored in different partitions on the same disk. Later, you can actually view the file /proc/cmdline to see what boot options (including default boot options) were used.

31.2 Theory

31.2.1 Kernel boot sequence

A UNIX kernel, to be booted, must be loaded into memory from disk and be executed. The execution of the kernel causes it to uncompress itself and then run. [The word boot itself comes from the concept that a computer cannot begin executing without program code, and program code cannot get into memory without other program code--like trying to lift yourself up by your bootstraps, and hence the name.] The first thing the kernel does after it runs is initialize various hardware devices. It then mounts the root file system on a specified partition. Once the root file system is mounted, the kernel executes /sbin/init to begin the UNIX operating system. This is how all UNIX systems begin life.

31.2.2 Master boot record

PCs begin life with a small program in the ROM BIOS that loads the very first sector of the disk into memory, called the boot sector of the master boot record or MBR. This piece of code is up to 512 bytes long and is expected to start the operating system. In the case of LINUX, the boot sector loads the file /boot/map, which contains a list of the precise location of the disk sectors that the LINUX kernel image (usually the file /boot/vmlinuz) spans. It loads each of these sectors, thus reconstructing the kernel image in memory. Then it jumps to the kernel to execute it.

You may ask how it is possible to load a file from a file system when the file system is not mounted. Further, the boot partition is a small and simple program and certainly does not support the many types of file systems and devices that the kernel image may reside in. Actually, lilo doesn't have to support a file system to access a file, as long as it has a list of the sectors that the file spans and is prepared to use the BIOS interrupts [Nothing to do with ``interrupting'' or hardware interrupts, but refers to BIOS functions that are available for use by the operating system. Hardware devices may insert custom BIOS functions to provided rudimentary support needed for themselves at startup. This support is distinct from that provided by the hardware device drivers of the booted kernel.] to read those sectors. If the file is never modified, that sector list will never change; this is how the /boot/map and /boot/vmlinuz files are loaded.

31.2.3 Booting partitions

In addition to the MBR, each primary partition has a boot sector that can boot the operating system in that partition. MS-DOS (Windows) partitions have this, and hence lilo can optionally load and execute these partition boot sectors to start a Windows installation in another partition.

31.2.4 Limitations

BIOSs have inherited several limitations because of lack of foresight of their designers.

First, some BIOSs do not support more than one IDE. [At least according to the lilo documentation.] I myself have not come across this as a problem.

The second limitation is most important to note. As explained, lilo uses BIOS functions to access the IDE drive, but the BIOS of a PC is often limited to accessing the first 1024 cylinders of the disk. Hence, whatever LILO reads must reside within the first 1024 cylinders (the first 500 megabytes of disk space). Here is the list of things whose sectors are required to be within this space:

1.
/boot/vmlinuz
2.
Various lilo files /boot/*.b
3.
Any non-LINUX partition boot sector you would like to boot
However a LINUX root partition can reside anywhere because the boot sector program never reads this partition except for the abovementioned files. A scenario where the /boot/ directory is a small partition below the 500 megabyte boundary and the / partition is above the 500 megabyte boundary, is quite common. See page [*].

Note that newer ``LBA'' BIOS's support more than the first 512 megabytes--even up to 8 Gigabytes. I personally do not count on this.

31.3 lilo.conf and the lilo Command

To ``do a lilo'' means running the lilo command as root, with a correct /etc/lilo.conf file. The lilo.conf file will doubtless have been set up by your distribution (check yours). A typical lilo.conf file that allows booting of a Windows partition and two LINUX partitions is as follows:

 
 
 
 
5 
 
 
 
 
10 
 
 
 
 
15 
 
 
 
 
20 
boot=/dev/hda
prompt
timeout = 50
compact
vga = extended
lock
password = jAN]")Wo
restricted
append = "ether=9,0x300,0xd0000,0xd4000,eth0 hisax=1,3,5,0xd8000,0xd80,HiSax"
image = /boot/vmlinuz-2.2.17
        label = linux
        root = /dev/hda5
        read-only
image = /boot/vmlinuz-2.0.38
        label = linux-old
        root = /dev/hda6
        read-only
other = /dev/hda2
        label = win
        table = /dev/hda

Running lilo will install into the MBR a boot loader that understands where to get the /boot/map file, which in turn understands where to get the /boot/vmlinuz-2.2.12-20 file. It gives output like:

 
 
 
 
[root@cericon]# lilo
Added linux *
Added linux-old
Added win

It also backs up your existing MBR, if this has not previously been done, into a file /boot/boot.0300 (where 0300 refers to the device's major and minor number).

Let's go through the options:

boot
Device to boot. It will most always be /dev/hda or /dev/sda.
prompt
Display a prompt where the user can enter the OS to boot.
timeout
How many tenths of a seconds to display the prompt (after which the first image is booted).
compact
String together adjacent sector reads. This makes the kernel load much faster.
vga
We would like 80x50 text mode. Your startup scripts may reset this to 80x25--search /etc/rc.d recursively for any file containing `` textmode''.
lock
Always default to boot the last OS booted [A very useful feature which is seldom used.].
password
Require a password to boot.
restricted
Require a password only if someone attempts to enter special options at the LILO: prompt.
append
A kernel boot option. Kernel boot options are central to lilo and kernel modules and are discussed in Chapter 42.5. They are mostly not needed in simple installations.
image
A LINUX kernel to boot.
label
The text to type at the boot prompt to cause this kernel/partition to boot.
root
The root file system that the kernel must mount.
read-only
Flag to specify that the root file system must initially be mounted read-only.
other
Some other operating system to boot: in this case, a Windows partition.
table
Partition table info to be passed to the partition boot sector.

Further other = partitions can follow, and many image = kernel images are allowed.

The preceding lilo.conf file assumed a partition scheme as follows:

/dev/hda1
10-megabyte ext2 partition to be mounted on /boot.
/dev/hda2
Windows 98 partition over 500 megabytes in size.
/dev/hda3
Extended partition.
/dev/hda4
Unused primary partition.
/dev/hda5
ext2 root file system.
/dev/hda6
Second ext2 root file system containing an older distribution.
/dev/hda?
LINUX swap, /home, and other partitions.

31.4 Creating Boot Floppy Disks

If LILO is broken or absent, we require an alternative boot method. A floppy disk capable of booting our system must contain a kernel image, the means to load the image into memory, and the means to mount /dev/hda5 as the root file system. To create such a floppy, insert a new floppy disk into a running LINUX system, and overwrite it with the following commands:

 
 
dd if=/boot/vmlinuz-2.2.17 of=/dev/fd0
rdev /dev/fd0 /dev/hda5

Then simply boot the floppy. This procedure requires a second LINUX installation at least. If you only have an MS-DOS or Windows system at your disposal then you will have to download the RAWRITE.EXE utility as well as a raw boot disk image. Many of these are available and will enable you to create a boot floppy from a DOS prompt. I will not go into detail about this here.

31.5 SCSI Installation Complications and initrd

Some of the following descriptions may be difficult to understand without knowledge of kernel modules explained in Chapter 42. You may want to come back to it later.

Consider a system with zero IDE disks and one SCSI disk containing a LINUX installation. There are BIOS interrupts to read the SCSI disk, just as there were for the IDE, so LILO can happily access a kernel image somewhere inside the SCSI partition. However, the kernel is going to be lost without a kernel module [See Chapter 42. The kernel doesn't support every possible kind of hardware out there all by itself. It is actually divided into a main part (the kernel image discussed in this chapter) and hundreds of modules (loadable parts that reside in /lib/modules/) that support the many type of SCSI, network, sound etc., peripheral devices.] that understands the particular SCSI driver. So although the kernel can load and execute, it won't be able to mount its root file system without loading a SCSI module first. But the module itself resides in the root file system in /lib/modules/. This is a tricky situation to solve and is done in one of two ways: either (a) using a kernel with preenabled SCSI support or (b) using what is known as an initrd preliminary root file system image.

The first method is what I recommend. It's a straightforward (though time-consuming) procedure to create a kernel with SCSI support for your SCSI card built-in (and not in a separate module). Built-in SCSI and network drivers will also autodetect cards most of the time, allowing immediate access to the device--they will work without being given any options [Discussed in Chapter 42.] and, most importantly, without your having to read up on how to configure them. This setup is known as compiled-in support for a hardware driver (as opposed to module support for the driver). The resulting kernel image will be larger by an amount equal to the size of module. Chapter 42 discusses such kernel compiles.

The second method is faster but trickier. LINUX supports what is known as an initrd image ( initial rAM disk image). This is a small, +1.5 megabyte file system that is loaded by LILO and mounted by the kernel instead of the real file system. The kernel mounts this file system as a RAM disk, executes the file /linuxrc, and then only mounts the real file system.

31.6 Creating an initrd Image

Start by creating a small file system. Make a directory ~/initrd and copy the following files into it.

 
 
 
 
5 
 
 
 
 
10 
 
 
 
 
15 
 
 
drwxr-xr-x    7 root     root         1024 Sep 14 20:12 initrd/
drwxr-xr-x    2 root     root         1024 Sep 14 20:12 initrd/bin/
-rwxr-xr-x    1 root     root       436328 Sep 14 20:12 initrd/bin/insmod
-rwxr-xr-x    1 root     root       424680 Sep 14 20:12 initrd/bin/sash
drwxr-xr-x    2 root     root         1024 Sep 14 20:12 initrd/dev/
crw-r--r--    1 root     root       5,   1 Sep 14 20:12 initrd/dev/console
crw-r--r--    1 root     root       1,   3 Sep 14 20:12 initrd/dev/null
brw-r--r--    1 root     root       1,   1 Sep 14 20:12 initrd/dev/ram
crw-r--r--    1 root     root       4,   0 Sep 14 20:12 initrd/dev/systty
crw-r--r--    1 root     root       4,   1 Sep 14 20:12 initrd/dev/tty1
crw-r--r--    1 root     root       4,   1 Sep 14 20:12 initrd/dev/tty2
crw-r--r--    1 root     root       4,   1 Sep 14 20:12 initrd/dev/tty3
crw-r--r--    1 root     root       4,   1 Sep 14 20:12 initrd/dev/tty4
drwxr-xr-x    2 root     root         1024 Sep 14 20:12 initrd/etc/
drwxr-xr-x    2 root     root         1024 Sep 14 20:12 initrd/lib/
-rwxr-xr-x    1 root     root           76 Sep 14 20:12 initrd/linuxrc
drwxr-xr-x    2 root     root         1024 Sep 14 20:12 initrd/loopfs/

On my system, the file initrd/bin/insmod is the statically linked [meaning it does not require shared libraries.] version copied from /sbin/insmod.static--a member of the modutils-2.3.13 package. initrd/bin/sash is a statically linked shell from the sash-3.4 package. You can recompile insmod from source if you don't have a statically linked version. Alternatively, copy the needed DLLs from /lib/ to initrd/lib/. (You can get the list of required DLLs by running ldd /sbin/insmod. Don't forget to also copy symlinks and run strip -s <lib> to reduce the size of the DLLs.)

Now copy into the initrd/lib/ directory the SCSI modules you require. For example, if we have an Adaptec AIC-7850 SCSI adapter, we would require the aic7xxx.o module from /lib/modules/<version>/scsi/aic7xxx.o. Then, place it in the initrd/lib/ directory.

 
-rw-r--r--    1 root     root       129448 Sep 27  1999 initrd/lib/aic7xxx.o

The file initrd/linuxrc should contain a script to load all the modules needed for the kernel to access the SCSI partition. In this case, just the aic7xxx module [ insmod can take options such as the IRQ and IO-port for the device. See Chapter 42.]:

 
 
 
 
5 
 
#!/bin/sash
 
aliasall
 
echo "Loading aic7xxx module"
insmod /lib/aic7xxx.o 

Now double-check all your permissions and then chroot to the file system for testing.

 
 
chroot ~/initrd /bin/sash
/linuxrc

Now, create a file system image similar to that in Section 19.9:

 
 
 
 
5 
 
 
 
dd if=/dev/zero of=~/file-inird count=2500 bs=1024
losetup /dev/loop0 ~/file-inird
mke2fs /dev/loop0
mkdir ~/mnt
mount /dev/loop0 ~/mnt
cp -a initrd/* ~/mnt/
umount ~/mnt
losetup -d /dev/loop0

Finally, gzip the file system to an appropriately named file:

 
gzip -c ~/file-inird > initrd-<kernel-version>

31.7 Modifying lilo.conf for initrd

Your lilo.conf file can be changed slightly to force use of an initrd file system. Simply add the initrd option. For example:

 
 
 
 
5 
 
 
 
 
10 
 
boot=/dev/sda
prompt
timeout = 50
compact
vga = extended
linear
image = /boot/vmlinuz-2.2.17
        initrd = /boot/initrd-2.2.17
        label = linux
        root = /dev/sda1
        read-only

Notice the use of the linear option. This is a BIOS trick that you can read about in lilo(5). It is often necessary but can make SCSI disks nonportable to different BIOSs (meaning that you will have to rerun lilo if you move the disk to a different computer).

31.8 Using mkinitrd

Now that you have learned the manual method of creating an initrd image, you can read the mkinitrd man page. It creates an image in a single command. This is command is peculiar to RedHat.


next up previous contents
Next: 32. init, ? getty, Up: rute Previous: 30. exim and sendmail   Contents