A GRUB Tutorial 

Hoyt Duff

What makes GRUB a good alternative to LILO? 

The LInux LOader has been the standard bootloader for Linux. It is well-documented and widely used, so why even bother with another bootloader?

The GRUB bootloader is interactive and supports a BASH-like command line which features autocomplete making the use of a "universal" boot floppy possible. GRUB understand filesystems and can search them for files, helping you find file names and boot unfamiliar systems. GRUB reads its configuration from a text file at each boot, so it doesn't have to be re-run with each configuration change. How often have you forgotten to do that with LILO? GRUB is network-aware and can be compiled to run with network support like bootp, rarp, DHCP and tftp. GRUB can hide and unhide partitions, allowing multi-booting of normally conflicting operating systems. Unlike most bootloaders that know the kernel location only from a map, GRUB can load a kernel from anywhere it can 'see' on the disk without knowing where the kernel is beforehand

device names 

GRUB device names are not like the Linux device names with which you are familiar. This is the biggest hurdle in understanding GRUB, so we'll address this first.

All the device names are enclosed in parentheses.

There are two device names: (fd) for floppy drives and (hd) for hard drives (yes, both IDE and SCSI).

Drives are numbered beginning with 0. The developers of GRUB claim a desire to "fix" this in future releases so that the first device is numbered 1 instead of 0, but we won't be holding our breath. Hard drives are numbered sequentially in the order that the are detected by the BIOS. Changing the BIOS boot order will change the GRUB device name, so be careful.

Partitions within a drive are numbered sequentially beginning with 0. BSD slices are handled in a slightly different manner and you should consult the GRUB docs for BSD specifics. Partition numbers of extended partitions are always counted from 4.

Our Example System 

Let's look at an example system that has a single floppy drive, an IDE drive connected as the primary master (three partitions - VFAT, EXT2 and Linux swap), an IDE drive at the secondary master (two partitions - vfat and ext2), as well as a SCSI drive that is not configured to be bootable (with a BSD installation).

Here's a table of how each partition would be named in LILO and in GRUB

LILO           GRUB
/dev/fd0       (fd0)
/dev/hda1      (hd0,0)
/dev/hda2      (hd0,1)
/dev/hda3      (hd0,2)
/dev/hdc1      (hd1,0)
/dev/hdc2      (hd1,1)
/dev/scd0      (hd2,0)

Editing the GRUB Menu 

Let's edit Entry 6 first. On our example system, Windows98 is installed on the first partition of the first disk. Mounting the floppy and using our favorite text editor, we now have the following:

A Windows Menu 

Example 1. Entry 6: Sample chainloaded OS.

title Windows 98ME

root (hd0,0)

makeactive

# Chainload from the first sector
chainloader +1

# If you want DOS, but Windows NT is installed, then use:
# chainloader /bootsect.dos

and then we save the file. It's not necessary to follow up by running GRUB as you do with LILO. How many times have you changed /etc/lilo.conf and forgotten to do just that? We have lost count.

A Linux Menu 

Now, we'll edit the GNU/Linux entry to accommodate our Mandrake install on a reiserfs partition.

Example 2. Entry 5: Sample GNU/Linux boot. title GNU/Linux (hd0s2)

root (hd0,1)

kernel /boot/vmlinuz-2.4.3-20mdk root=/dev/hda2 read-only

# Don't forget that some distributions rely on an initial ramdisk:
initrd /boot/ initrd-2.4.3-20mdk.img

Note that we changed the kernel name to match the one we will be using, uncommented the initrd entry (that's necessary for us to use the reiserfs) and named the initrd file appropriately.

We have another Linux distro installed on our second drive on the ext2 partition, so we'll add another entry to our menu. Note that the entries are sequentially numbered, but this is just for our own housekeeping use. If we want to use the default command in our menu to specify a default entry, we need to remember that the entries are numbered by GRUB beginning with zero.

Since no special drivers are being loaded, there is no initrd. Our new entry looks like:

Example 3. Entry 7: GNU/Linux boot.

title RedHat 7.1
root (hd1,1)
kernel /boot/vmlinuz root=/dev/hdc2 read-only

# Note that we used the Linux name for the root partition.

# Don't forget that some distributions rely on an initial ramdisk:
#initrd /boot/initrd

A DOS Menu 

Gluttons for punishment that we are, we also have DOS 6.22 installed on the first partition of our second IDE disk. We need to hide the Windows partition, unhide the DOS partition and make the DOS partition active to keep the DOS bootloader happy. Since we do that for DOS, we also must do it for Windows, so don't forget to edit that menu entry as well.

Windows and DOS are somewhat egomaniacal and need to believe that they are the only Microsoft OS on the drive. We can fool them by using the hide/unhide commands. They also want to believe that they are on the first disk. In our example, DOS is on the second disk so we need to re-map the drives to fool the OS.

Example 4. Entry 8: chainloaded OS. title DOS 6.22

 # Let's fool DOS into thinking it's alone in the world by hiding Windows.
 hide (hd0,0)
 unhide (hd1,0)

 # Now we make DOS think it's on the first drive so it's happy.
 map (hd0) (hd1)
 map (hd1) (hd0)

 # Now we can begin to mount the root partition and
 # load the chainloader that loads the Windows OS.

 # Our root is the first partition of the first drive (since we switched them).
 root (hd1,0)

 # Here, we could use the rootnoverify which will set the root partition, but not
 # mount it. This is especially useful if the kernel is somewhere on the disk
 # that GRUB can't see, but it can see the chainloader.
 # DOS and Windows seem to work well both ways.

 # And we make it the active partition.
 makeactive

 # The "+1" tells GRUB to boot the chainloader from the first sector,
 # rather than attempt to load Windows by GRUB itself.
 chainloader +1

We now need to go back and edit our Windows entry to reverse the hide/unhide process we now use for DOS so Windows will boot correctly, a trick LILO can't accomplish. We don't need to use map again because that is only in effect for the current session and is reset upon reboot.

A FreeBSD Menu 

Finally, we have FreeBSD installed on our SCSI drive, so the menu item for that will look like:

Example 5. Entry 9: BSD

 title FreeBSD 4.3

 # Remember, we are using the SCSI drive and BSD does "slices", so the root
 # partition will be "a".
 root (hd2,a) 2

 # We don't call the kernel, but do call the BSD bootloader.
 kernel /boot/loader

Note the number "2" after the root command. This is the HDBIAS and tells a BSD kernel how many BIOS drive numbers are on controllers before it. In our example, there are two.

Do I Really Need a GRUB Menu? 

You don't need a GRUB menu, but if you want one, it is a simple text file created with any editor (even a Windows/DOS editor if you insist). It's named menu.lst (as in "el"-s-t, not 'one'-s-t — some fonts make this impossible to distinguish) and is kept in /boot/grub. Use the example shown here or in the GRUB docs to create one. If it fails to work, your computer won't crash and your data won't be lost, you'll just have to boot manually and try again.

Installing GRUB on Your Hard Drive 

We have assumed that you are experimenting with GRUB from a boot floppy, but GRUB can happily live in your MBR just as LILO did. Installing is incredibly easy:

# grub-install

does the trick.

If you don't like GRUB and want to return to LILO,

# lilo

If you don't like GRUB and want to return to the Windows bootloader (we can't imagine why, but it's your computer), boot from the Emergency Boot Floppy and run:

a:\fdisk /mbr

grub-install 

grub-install INSTALL_DEVICE

The device name INSTALL_DEVICE is an OS device name or a GRUB device name, e.g, '(hd0)' or /dev/fd0

Passwords 

For the paranoid among us ( and who shouldn't be a little paranoid about computer security), GRUB offers password protection of individual menu items.

To use passwords, first add a line at the beginning of the menu.lst file:

password <mypassword>

where <mypassword> is your password.

For each boot option you wish to password protect, add the command lock to the beginning of that section. Obviously, you want to have lock in the section that boots to the partition that hold menu.lst. However, don't consider password protection to be any kind of real security since anyone could easily bypass this by using their own GRUB boot floppy.

GRUB Docs and the Info Command 

We need to congratulate the developers of GRUB on one thing that sets them apart from many other Open Source projects — the availability of excellent documentation. You access it using info (as in info grub at a shell prompt) instead of using the man page system. The documentation contains detailed explanations of the workings of GRUB including a surfeit of excellent examples as well as a tutorial.

What is initrd? 

If you're curious as to what is in the initrd (initial ramdisk) file, it's a gzipped filesystem image! Copy it to another location and rename it with a .gz extension. Then, gunzip it and it loses the .gz extension. Mount this file (on /mnt/image in our example) with

# mount -o loop initrd /mnt/image

and you can browse it like any filesystem. For more details, read The Loopback Root Filesystem HOWTO at http://www.linuxdoc.org/HOWTO/mini/Loopback-Root-FS.html#toc2r .

GRUB at the GRUB Shell Prompt 

Create a boot floppy from the boot floppy image as described previously and boot your computer from it.

Because the boot floppy has a /boot/grub/menu.lst on it, you will see the supplied boot menu which will not likely be set to any useful defaults for you.

Here we see the menu options. If you highlight the one for GNU/Linux and press Enter, you'll see:

The "e" command allow us to edit each line individually and the "o" command adds a line for us to include our initrd.

Finally, we use the "b" command to boot into our Mandrake 8.0 installation.

Hardcore GRUB — No Menu 

Let's try doing the same thing using the GRUB command line, using the "c" command to get there. After seeing a message, we are greeted by the GRUB prompt:

grub>

We set the root partition first, but let's see what command completion will do for us, so type:

grub> root (

and then press the TAB key. We are told:

grub> root ( Possible disks are: fd0 hd0 hd1 hd2

Remember that these are our floppy drive, the primary master IDE drive, the secondary master IDE drive and the SCSI drive, detected by GRUB in their BIOS boot order.

We now type some more:

grub> root (hd0,

and press TAB to see a list of all partitions on the drive.

grub> root (hd0,

Possible Partitions are: Partition num: 0, Filesystem type is fat, partition type 0xc Partition num: 1, Filesystem type is ext2, partition type 0x83 Partition num: 2, Filesystem type is unknown, partition type 0x82

We will complete the entry for partition 1, our GNU/Linux installation and press Enter.

Second, we want to tell GRUB what kernel to boot, but we're not certain of the full name, so we use the find command (since we have mounted the partition using the root command). We'll use the autocomplete function to help us, so type:

grub > kernel /

and press the TAB. It will display the possible completions like the Bash shell. Continue until the full path and name of the kernel are displayed. If you want to add kernel arguments, they follow at the end of this line. Then press Enter.

grub> kernel /boot/vmlinuz-2.4.3-20mdk root=/dev/hda2

Third, we need to load the initrd image so the Linux kernel has the reiserfs module available to it. We do so with the initrd command and use the autocomplete function as before.

grub> initrd /boot/initrd-2.4.3-20mdk.img

And finally, since we are working at the GRUB shell prompt, we give the boot command.

grub> boot

and we soon see . . .

login:

Success!!!

Conclusion 

GRUB is a nice bit of kit not only for booting your favorite OS, but also for rescue and recovery work. Simple to use, but uutterly complex in the depth of ssophisticationit offers, you owe it to yourself to check it out.

Web Resources 

GNU GRUB http://www.gnu.org/software/grub/grub.html

GRUB HOWTO by Fabio Fracassi http://archive.linuxfromscratch.org/lfs-hints/html/GRUB-Howto.html

This one is good for keyboard key translation examples.

Multiboot with GRUB Mini-HOWTO http://www.linuxdoc.org/HOWTO/mini/Multiboot-with-GRUB.html

Useful Commands 

We have explored the more common GRUB commands. Here are some others that you may find useful

cat
prints the contents of a file.
color
if you want to get fancy, add colour to your menu. Try color green/black light-green/black. Go crazy, Fabio.
find
search for the FILENAME in all the partitions and print a list of devices where the file is found.
geometry
print the geometry of the device. From the shell, you can set the geometry of the drive if necessary.
setkey
allows you to remap keys on your keyboard
splashscreen
you can use a splashscreen if you just need to feel pretty.
terminal
use a remote terminal when booting