Open Source

Introduction to Linux boot loaders

See how the Linux boot loaders LILO and GRUB work, and how to configure and manage them.


One of the remaining mysteries of Linux for many people is how to change the system startup. Sure, you've completed the installation, but now you want to tweak it a little bit. Perhaps you've upgraded your kernel and can't figure out how to make the system boot it instead of your old kernel. Perhaps you want to password-protect the booting of your Linux workstation. These are all great goals, but how do you accomplish them?

In this Daily Drill Down, we will take a look at Linux boot loaders. A boot loader is the program that sits in your computer's Master Boot Record, or MBR, or at the beginning of your bootable partition. Every operating system uses a boot loader of some sort; without it, the computer would not be able to boot into your operating system. Windows comes with its own boot loader that is transparent to the end user, the same as in DOS. It will simply boot Windows or DOS, whichever OS you have installed. You can purchase third-party boot loaders for Windows, which allow you to dual-boot between different operating systems on your computer. One example is PowerQuest's BootMagic, which is also used by default for the OS/2 operating system.

With Linux, you can also use BootMagic if you feel like paying for a boot loader. BootMagic comes with PartitionMagic and you may have the need for an on-the-fly partitioning utility. However, if you do not need this, Linux comes with two excellent boot loaders: LILO and GRUB.

Introduction to LILO and GRUB
LILO (current version is 21.7.5) was the first Linux boot loader, and its name simply stands for “LInux LOader.” You will never need to download it because all Linux distributions come with it.

GRUB is a newer boot loader that at one point was a little more advanced than LILO. Its name stands for GRand Unified Bootloader. I find GRUB a little more difficult to use than LILO, and it is no longer any more advanced than LILO is. It offered a graphical boot menu before LILO did, and it was a text ANSI-based menu at that. Now, LILO offers a true graphical boot menu and is just as powerful, if not more so, than GRUB.

Using LILO
We will first take a look at LILO. The LILO configuration file is typically /etc/lilo.conf, and it contains information on the possible kernels, boot images, and defaults for LILO. Because LILO can dual-boot between Linux and Windows, as well as many other operating systems, your LILO configuration file can become quite confusing. On one system, I have LILO configured to boot between eight versions of Linux-Mandrake, Debian, and SuSE. So, as you can see, there are no real limits to what you can accomplish with LILO.

Let's take a look at an example lilo.conf file:
boot=/dev/hde
map=/boot/map
install=/boot/boot.b
vga=ext
default=linux
lba32
prompt
timeout=50
password=secret
restricted
message=/boot/message-graphic
menu-scheme=wb:bw:wb:bw
image=/boot/vmlinuz
     label=linux
root=/dev/hde1
initrd=/boot/initrd.img
append=" hdb=ide-scsi"
read-only
image=/boot/vmlinuz
     label=failsafe
root=/dev/hde1
initrd=/boot/initrd.img
append=" hdb=ide-scsi failsafe"
read-only
other=/dev/fd0
     label=floppy
unsafe
image=/boot/vmlinuz-2.2
     label=linux2.2
root=/dev/hde1
initrd=/boot/initrd-2.2.img
append=" hdb=ide-scsi"
read-only


This is the configuration file I use on a Linux-Mandrake 8.0 system. It's very straightforward and easy to follow.

Keywords
The boot keyword tells LILO which hard drive contains the boot sector that is read. This should be the first hard drive in your system. We see that /dev/hde is the value here, which specifies the first ATA100 drive in the system. If you have ATA33 or ATA66 drives, this will likely be /dev/hda instead.

The map keyword specifies the location of the map file. This is typically /boot/map. If you do a directory listing in your /boot directory, you should see the map file there.

The install keyword contains the name of the file to be used as the new boot loader. With versions of LILO 21.5 and higher, this can be either boot-text.b or boot-menu.b. In our case, we use /boot/boot.b, which is actually a symbolic link to boot-menu.b. You will typically want to use boot-menu.b, as that provides you the graphical menu you see when you start your computer, while boot-text.b only exists for those who prefer a simple LILO prompt instead of the menu.

The vga keyword determines which VGA mode LILO will boot with. If you wish to boot into straight 80x25 mode, use the word "normal" here; if you wish to boot into 80x50 mode, use ext. If you want to know what VGA modes are available, use the word ask and LILO will present you with a list of VGA modes from which to choose.

The default keyword determines which image is the default to be loaded. In this case, we want the linux image to be loaded by default.

The lba32 keyword tells LILO to generate 32-bit logical block addresses instead of sector/head/cylinder addresses. This is recommended for all recent drives, as it allows LILO to boot from partitions beyond the 1024-cylinder barrier.

The prompt keyword tells LILO to issue the boot prompt and wait for user input before proceeding. The timeout keyword tells LILO how long to wait in tenths of a second. So the value of 50 in the timeout section tells LILO to wait 5 seconds.

The password keyword defines a password that must be used to boot the system. In this case, our password is secret. If you wish to have the system require the password to boot, remove the restricted keyword from the file. If you only want a password to be required if the user tries to append options to the kernel at the boot prompt, leave the restricted keyword where it is. The restricted keyword is generally used when you want the system to be able to boot without human intervention but want to prevent people from changing kernel options. These keywords can also be used in the image sections, so you can password-protect certain images completely, while using the restricted keyword with only some other images. If you wish to mix and match restricted and unrestricted images, define the password in the global section and use the restricted keyword in the images you wish to be able to boot without human intervention (usually the default image) and omit it from the other sections so that a password is required to boot them.

The message keyword tells LILO which file to use that contains the message to display before the boot prompt. For our graphical menu, we are using /boot/message-graphic, which contains the graphic for our graphical menu. If you were using the text loader, you could enter some text in the file to be displayed before the boot prompt. Whenever you change the message file, you will need to rerun LILO to rebuild the map file.

The menu-scheme keyword determines the color scheme to use with graphical booting. It follows the syntax: <text>:<highlight>:<border>:<title>, which in our case is wb:bw:wb:bw. This means we will have white on blue for the text and border, with blue on white for the highlight and title. The letters you can use are kbgcrmyw, which stand for blacK, Blue, Green, Cyan, Red, Magenta, Yellow, and White, respectively. Use uppercase letters if you want the color to be intense.

Finally, we come to the section defining our images to boot from. Each image section has the same structure, which consists of a starting image keyword that determines the Linux image to boot; this will usually be /boot/vmlinuz-[kernel_version]. In most cases, /boot/vmlinuz will be a symlink to a real image file, like /boot/vmlinuz-2.4.3-20mdk.

Next, you define the name of the image with the label keyword. The first one we define is linux, which is our default image. Further on, we define labels like linux-nonfb for a nonframebuffer kernel and linux2.2 for a 2.2 kernel.

You also need to define the root directory for this Linux installation with the root keyword. Here, we define /dev/hde1, which we mount as / (root).

If you have a SCSI adapter or if you use the ReiserFS filesystem, you will probably need an initrd image. This image is the initial ramdisk to be loaded for the specified kernel. This is particularly needed in systems where you boot off a SCSI drive or you have your root partition formatted to ReiserFS. The initrd image will contain the modules for those devices; without the modules available, you will not be able to boot off of your SCSI devices or mount your root partition.

The append keyword tells LILO what options to pass to the kernel when booting. In this case, we pass "hdb=ide-scsi" to the kernel, which tells the kernel that the device /dev/hdb, our IDE CD writer, is to be used with the ide-scsi module. This allows us to use tools like cdrecord to write to our IDE CD-RW with the SCSI emulation for IDE devices driver.

The read-only keyword tells LILO to mount the root partition as read-only. Don't worry, because later the startup procedures will remount the root filesystem as read-write, after performing a check on it. This is just a safety precaution.

You can have as many image definitions as you want. As stated earlier, I have a system that boots between 10 different Linux distributions, so my lilo.conf file is full of image directives. You can also see here that you can tell LILO to boot from other devices, like the floppy disk. This can be beneficial because it will allow you to prevent people from putting their own floppy boot disk into the system to boot off of by telling the BIOS to boot from the hard drive only. By password-protecting LILO and your BIOS, you can ensure that only authorized people will be able to boot from a floppy.

To save your changes and regenerate the boot image, you will need to run the lilo command. I suggest using:
/sbin/lilo -v

This will tell LILO to be verbose and tell you what it is doing as it does it. This way, if you do have any errors in your file, you can determine quickly what the error is.

Using GRUB
GRUB works in a very different way. It comes with an interactive script called grub-install, which is how you should initially configure it, unless you really know what you're doing. You will need to have GRUB installed first; most distributions also come with GRUB, but if not, you can download it from the GNU.org site.

To begin the configuration, issue the following as root:
grub-install /dev/hde

where /dev/hde is the primary drive to boot from. Again, /dev/hde is the primary ATA100 drive, but if you use ATA33 or ATA66 drives, be sure to use /dev/hda.

Once grub-install runs for the first time, it will create a file called /boot/grub/device.map and will print the contents of that file to the screen. This will list all of the drive devices on your system, including your floppy drive. After running grub-install here, my /boot/grub/device.map file looked like Table A.

Table A
(fd0) /dev/fd0
(hd0) /dev/hde
(hd1) /dev/hdf
(hd2) /dev/hdg
The device.map file

If this looks correct, you will then need to create the GRUB configuration file: /boot/grub/menu.lst. Let's look at an example configuration file.

Keywords
The default keyword tells GRUB to boot the first definition by default; in this case, it will be the one titled Linux.

The timeout keyword tells GRUB to wait 5 seconds before booting automatically. Unlike LILO, GRUB uses seconds, not tenths of a second.

The i18n keyword tells GRUB which file to use for its message file, which will be shown prior to the grub> prompt. This tells GRUB to use the file /boot/grub/messages, located on the first partition on the first hard drive (hd0,0).

The password keyword defines the password required to start any interactive operations, such as editing menu entries and entering the command-line interface. In this fashion, you can prevent GRUB from doing anything other than starting the default operating system without the password, but you will need to use the lock keyword as we see in the second image (in the above configuration example). The lock keyword tells GRUB to only boot that image if a valid password is entered.

The title keyword starts an image definition. The first image we define, which we also have set to our default, is Linux.

The kernel keyword defines the kernel image to load and all other kernel options. Where LILO uses a number of entries to specify all of this information, GRUB uses a single line. The first part determines the location of the boot image. In this case, we are using /boot/vmlinuz, which is located on the first partition of the first hard drive. If boot is located on a different partition, say /dev/hde5, you would use (hd0,4) to tell GRUB to use the fifth partition of the first hard drive. Finally, you tell it the root directory to use, /dev/hde1, the initrd.img file to use, /boot/initrd.img, and the appended options, which in this case is hdb=ide-scsi, to load the ide-scsi module for our CD-RW. In the above example, the lines have wrapped; they are in fact all on the same line.

There are a few more options you can set to fine-tune GRUB, and browsing the info pages will give you that information. Type info grub to obtain detailed information about GRUB. But this should be enough to get you started.

Writing changes
Finally, to write your changes to the MBR, simply run
grub

as root. You will then be given a grub> prompt. Now you need to enter a few commands to install GRUB into your MBR.
grub> root (hd0,0)

This tells GRUB where the root device is located. In our case, /dev/hde1 is where our /boot partition is located, and thus our GRUB stage1 file, so we use (hd0,0). Next, you need to actually install GRUB into the MBR by using
grub> setup (hd0)

After this command is completed, GRUB will tell you if it was successful or not. You can now reboot and GRUB will be your default boot loader.

Conclusion
Of the two boot loaders, LILO is my preferred program. It handles my dual-booting perfectly, has a nice graphical interface at boot, and is much easier to configure. While GRUB is powerful, I find the configuration to be much more confusing than LILO. It also isn't as standard as LILO, nor has it been used quite as long. While GRUB works well, I find LILO works better.

At this point, you should be able to modify your system to your heart's content. While there are more advanced options you can use with both boot loaders, the info and man pages will provide you with the help you need if what has been illustrated here is not sufficient.

One final word of caution: Remember to have a working floppy boot disk before you start fiddling with LILO or GRUB. If you configure them incorrectly, you may be unable to start your system without having a valid and working boot disk first. You should have generated a boot floppy when you first installed Linux. Before changing configuration files for LILO and GRUB, boot off of your floppy disk to ensure it works.

About

Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

Editor's Picks

Free Newsletters, In your Inbox