LINUX GAZETTE

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]

"Linux Gazette...making Linux just a little more fun!"


The GNU GRUB Boot Loader

By Jaswinder Singh Kohli


What is a boot loader?

A boot loader is a program that resides in the starting sectors of a disk, e.g., the MBR (Master Boot Record) of the hard disk. After testing the system during bootup, the BIOS (Basic Input/Output System) tranfers control to the MBR if the system is set to be booted from there. Then the program residing in MBR gets executed. This program is called the boot loader. Its duty is to transfer control to the operating system, which will then proceed with the boot process.

There are a lot of boot loader programs available, including GNU GRUB (Grand Unified Boot Loader), Bootmanager, LILO (LInux LOader), NTLDR (boot loader for Windows NT systems), etc. I've chosen to discuss GNU GRUB and how to use it.

What is GRUB?

GRUB is a very powerful boot loader that can load a variety of operating systems such as Windows, DOS, Linux, GNU Hurd, *BSD, etc.

Currently LILO is the most popular boot loader, used by almost everyone with multiboot systems. But if you use LILO, you have to remember to rerun LILO every time you change your configuration or install a new kernel. Also, LILO has less flexibility than GRUB.

GRUB is another name for flexibility. Its latest release, 0.5.96.1, supports ext2 (a file system Linux uses), FAT16 and FAT32 (used by Win9x and ME), FFS (Fast File System used by *BSD UNIX), ReiserFS (a new journalling file system developed for Linux and integrated into Linux Kernel 2.4.1), and minix (an old file system developed for the MINIX OS, also used by earlier Linux). With GRUB, you can "see" into these file systems without even booting an operating system. For example, if you want to see the date and time stored in a text file and don't have time for the whole operating system to boot, you can use GRUB's shell (prompt "grup>) and type:

grub> cat (partition number)/home/god/filename.txt.  
You'll have all your file system contents, including dates and times.

The best use of GRUB is that you can load any kernel on any partition right out of the box. For example, if you forget adding the newly compiled kernel to the list, you would normally need to boot, add it to the list and then reboot to use it. But with GRUB, you can simply use the shell and load the desired kernel image.

I'll now explain the three primary steps to using GRUB: compilation, installation and configuration.

STEP 1: Compiling and Installing GRUB

Download the source of GRUB from ftp://alpha.gnu.org/pub/gnu/grub.

Extract the compressed archive as "tar -xvzf filename.tar.gz"/ For me the filename was grub-0.5.96.1.tar.gz, so I did

# tar -xvzf grub-0.5.96.1.tar.gz
This command extracted a lot of files and directories to a directory called grub-0.5.96.1 Now do the following:
[root@heaven ~/grub-0.5.96.1 ]# ./configure

If you want to customize GRUB to include particular filesystem and network-card support, or to remove support of network cards you don't need, run:

[root@heaven ~/grub-0.5.96.1 ]# ./configure --help

This command will show you all the options. Now use the --enable and --disable prefixes to add or remove support for certain cards.

(NOTE: GRUB supports network booting.)

To start the compilation process, type:

[root@heaven ~/grub-0.5.96.1 ]# make

To install all the files in their proper places, type:

[root@heaven ~/grub-0.5.96.1 ]# make install

Now you are ready to really install grub GRUB.

It's a good idea to keep all of GRUB's boot-related files in a directory such as /boot/grub . To do this, follow this simple procedure:

1. By default all the files of GRUB are either installed in /usr/share/grub/i386-pc or /usr/local/share/grub/i386-pc depending upon how your shell variables are set.

2. Make a new directory called /boot/grub. Then copy the following files to this directory:

stage1
stage2
*_stage1_5

I will explain these files later. Also copy the GRUB program (which may be in /usr/sbin or /usr/local/sbin) to the /boot/grub directory.

Before installing GRUB, you need to know how GRUB understands your hard drive and partition information. First of all, counting starts from 0, not from 1. In Linux, your first hard drive attached to the primary master controller is called "hda". In GRUB it becomes "hd0". Likewise, your first floppy drive in GRUB is "fd0". So the first, second and third partitions on the first hard disk (hda1, hda2 and hda3), become "hd0,0", "hd0,1" and "hd0,2" in GRUB. NOTE: the comma is an integral part of GRUB partition nomenclature.

To integrate the two fields (disk drive number and partition number) around the comma into one, use parentheses. For example: (hd0,0) (hd0,1) (hd0,2) and so on. (hd0,0) is first partition on first hard disk. Similarly, (hd1,5) is the sixth partition on second hard disk and (hd2,0) is first partition on third hard disk.

Step 2: Installing GRUB

Installing GRUB can be broken into three separate parts:

  1. Installation of "stage1" in MBR.
  2. Setting up the address or location, "stage2".
  3. Setting up a boot menu or set of options to choose which operating oystem to boot.

Start installing GRUB by issuing the following command:

[root@heaven /boot/grub ]# ./grub

This command probes devices to guess BIOS drives and produces an output message. This may take a long time.

end_request: I/O error, dev 02:00 (floppy), sector 0

    GRUB  version 0.5.96.1  (640K lower / 3072K upper memory)

NOTE: Although it may seem surprising, GRUB does have minimal Bash-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. You may be surprised to see this feature. Something like this then appears:

grub> 

Now, I assume that you have installed your Linux distro in the first extended partition in the first disk or /dev/hda5. Remember the GRUB naming convention and rename the above to (hd0,4). Type the following command:

grub> install (hd0,4)/boot/grub/stage1 (hd0) (hd0,4)/boot/grub/stage2 p (hd0,4)/boot/grub/menu.conf
Now let's examine this command in detail:
install
a built-in command that tells GRUB to install (hd0,4)/boot/grub/grub/stage1 to (hd0), the Master Boot Record.
(hd0,4)/boot/grub/stage2
tells grub where the stage2 image is located.
p with the the following options: (hd0,4)/boot/grub/menu.conf
sets the configuration file for displaying nice menus. I will later discuss the structure of the configuration file.

We can also summarize that command as follows:

  1. install
  2. source_of_stage1
  3. where_to_install
  4. source_of_stage2
  5. p source_of_configuration_file

You have now completed the basic hard drive installation.

Installation on the floppy:

To install GRUB on a floppy you need to know the 'dd' command and how it works. For a GRUB bootable floppy you need to put the stage1 and stage2 files on the starting sectors of floppy.

Installing stage1 on a floppy

Insert a formatted floppy disk and type:

[root@heaven /boot/grub ]# dd if=stage1 of=/dev/fd0 bs=512 count=1

Again, lets examine the command in detail:

if=input file
i.e., stage1
of=output file
i.e., floppy drive (this may be different on your computer)
bs=bytes to read and write
Here it is 512 bytes.
count=how many times to perform this operation
Each iteration copies the next "bs" number of blocks to the destination, consecuitively.

Installing stage2 on a floppy

[root@heaven /boot/grub ]# dd if=stage2 of=/dev/fd0 bs=512 seek=1

Everything here is same as stage1 except for a new item called seek. Seek skips 1 "bs" value. For example, in the above command bs is 512, so seek=1 will skip the first 512 bytes of space on the floppy disk and continue at the 513rd byte. This will preserve the first operation by not overwriting the first 512 bytes written on stage1.

You have now completed the basic floppy drive installation.

STEP 3: Configuring GRUB

In this section we will see how to boot into various operating systems and build the menu.conf file.

Let's start with boot procedures supported by GRUB. Booting can be done in two ways:

Boot procedure using method A:

  1. Set the root device or tell GRUB your root file system.
  2. Tell GRUB where your kernel image is and pass the parameters to the kernel.
  3. Reboot and try it.

To boot Linux, I have my kernel in /boot/ as bzImage and my root file system as /dev/hda5, or (hd0,4) in GRUB. So my booting procedure is as follows:

  1. root (hd0,4)   [This sets the root partition]
  2. kernel /boot/bzImage root=/dev/hda5   [This sets the kernel]
  3. boot   [This starts booting into Linux]

Boot procedure using method B (this method assumes that you have another boot manager such as LILO or NTLDR installed in the partition):

  1. Set the root partition but do not mount it.
  2. Make that partition active
  3. Set the first sector of the device to which the control has to be transfered with command chain loader.
  4. Reboot and try it.

Let's try another example with Windows installed in /dev/hda1 or (hd0,0). The procedure for booting with Windows is as follows:

  1. rootnoverify (hd0,0)
  2. makeactive
  3. chainloader +1   [+1 sets the first sector of the current root partition]
  4. boot   [transfers the control and quits GRUB]

The menu.conf file: this is used for booting multiple operating systems and menu building. Building the menu.conf file is not difficult. It uses plain English, as you will see in this section.

All the menu entries start with "title TITLENAME" without commas. You can set your TITLENAME to whatever you want.

To make the menu for booting Linux:

  1. Set the title.
  2. Set the root partition .
  3. Set the kernel with right kind of parameters.
  4. Boot

To make a working menu:

title Debian GNU/Linux 2.2 kernel 2.4.1
root (hd0,4)
kernel /boot/bzImage.2.4.1
boot
#----

(Hash (#) in front of a line is a comment.)

To make a menu for Windows or DOS:

title Windoze 
rootnoverify (hd0,0)
makeactive
chainloader +1
boot
#----

What if you want to have two verisons of Windows installed--say one for yourself and the other for your family--but the second one won't install because it says Windows is already installed?

There is an easy way install two versions by hiding one partition during boot and then using the other. You can even password-protect your option so that no one loads your partition by mistake. Here's how to create two installations of Windows, hda1 and hda2 or (hd0,0) and (hd0,1), using the commands lock, password, hide and unhide.

For Windows "My Entry":

title My Entry
lock
unhide (hd0,0)
hide (hd0,1)
rootnoverify (hd0,0)
makeactive
chainloader +1
boot
#----

To use the lock command effectively you need to specify the password command near the start of the configuration file. The syntax of password command is as follows: password secret ("secret" is the password). At any time you can enter the password by pressing p.

For Windows "Family Entry"

title Family Entry
unhide (hd0,1)
hide (hd0,0)
rootnoverify (hd0,1)
makeactive
chainloader +1
boot
----

Anyone will be able to boot this entry as a password is not required.

Here's another interesting trick in the using password command. To hide the entries in the default menu listing or configuration file, you can load a personal listing by using the following command:

password secret

/boot/grub/secret-list.conf In this command, "secret" is the password and /boot/grub/secret-list.conf is the password file. Before doing this you should set the root directive or give the full path. For example:

password secret (hd0,4)/boot/grub/secret-list.conf

One more important command is the "map" command, which you can use when you have two hard disks and an operating system such as Windows which doesn't like to be booted from the second hard disk. For example, you can map hd0 as hd1 and hd1 as hd0. In other words, you can virtually swap the two hard disks and load the desired operating system. The commands are as follows:

grub> map (hd0) (hd1)
grub> map (hd1) (hd0)

For Booting FreeBSD:

title FreeBSD 4.0
root (hd0,4,a)
kernel /boot/loader
boot
#---- 

Here we are calling FreeBSD's loader. You see that the root (hd0,4,a) has three arguments as FreeBSD does virtual slicing of a single partition. We call the root partition "a". If FreeBSD occupies a complete second disk on your system, this would be root (hd0,a). So instead of calling the kernel we are calling the FreeBSD loader, which is better to talk to than the kernel.

(NOTE: I recommend that before trying OpenBSD and GNU/Hurd, you keep working on doing chain loading.)

You have now completed basic GRUB compiling, installing and configuring. The more you get to know GRUB, the more you will find GRUB to be an easy and powerful way to control booting.

Miscellaneous GRUB commands:

default xx
where xx is the default entry to boot.
timeout yy
where yy is the time (in seconds) after which the default entry will boot.
fallback zz
where zz is the entry which will boot if, after the timeout, the first entry fails to boot.
color
This is used for colorising the menu. Its syntax is: color normal current_selection. Both the fields can have two values as foreground/background For example:
color green/black or light-gray/blue
You can also use corresponding numbers.

REMEMBER: all values start from 0, so 0 is the first entry.

In my next article, I plan to test Fire GNU/Hurd and OpenBSD and maybe some networking bootup. You'll have to wait for at least three or more months as I will be taking my exams in between. Keep watching.

Any comments or mistakes can be forwarded to me at jskohli@fig.org.


Copyright © 2001, Jaswinder Singh Kohli.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 64 of Linux Gazette, March 2001

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]