Secrets of the Grand Unified Boot Loader

There are many times when you wish there was a good quick-reference for all of the common (and not so common) ways of using GRUB, which has fast become the preferred boot loader for personal computers. When asked what operating system they're running these days, some Linux users might even reply (with a grin) "GRUB!".

How to Create a "GRUB2 boot CDROM" using grub-mkrescue

Let's say you want to install Linux onto a Solid State Drive (SSD) which can't be recognized by your old BIOS. You can install Linux onto the SSD just fine, but you can't boot from it. What to do? Well, obviously you can boot from CD, since that's how you ran the installer in the first place. So you can build a GRUB2 bootable CDROM containing the kernel and initial ramdisk, along with the grub configuration file which was created when you installed Linux. The steps are as follows (obviously, you need to perform these steps somehow in a shell, before allowing the Linux installer to restart the machine to complete the installation, since the machine can't boot from the SSD on its own, as the BIOS doesn't recognize the SSD).

mkdir -p ./cdroot/boot/grub
mkdir -p ./cdroot/boot/grub/i386-pc
mkdir -p ./cdroot/boot/grub/locale
cp /boot/grub/grub.cfg ./cdroot/boot/grub
cp /usr/lib/grub/i386-pc/*.mod ./cdroot/boot/grub/i386-pc
cp /boot/initrd.img-* ./cdroot/boot/
cp /boot/vmlinuz-* ./cdroot/boot/
cp /boot/config-* ./cdroot/boot/
cp /boot/System.map-* ./cdroot/boot/

Edit the ./cdroot/boot/grub/grub.cfg so that it uses the CDROM e.g. (hd31) rather than the hard drive e.g. (/dev/sda,msdos1) in the set root part. Then you're ready to create a bootable ISO image containing the grub2 setup along with the Linux kernel and ramdisk, using the grub-mkrescue command. This is pretty handy, as it allows you to boot your system directly from CDROM if you (or some proprietary operating system which shall remain nameless) ever mess up your hard drive's MBR or grub configuration.

grub-mkrescue --modules="linux ext2 fshelp ls boot pc" --output=./rescue.iso ./cdroot

Copy the ./rescue.iso ISO image over to another machine, and burn it as follows:

wodim -v dev=/dev/scd0 -data ./rescue.iso

You'll usually need to use a second machine, since your CD-RW drive is likely still holding on to the install media, which only get ejected after the installer reboots the machine to finalize the installation (which is of course too late, since the machine can't boot from the SSD).

Remainder of this page is about the old GRUB

The remainder of this page is about the old GRUB, if you want to learn about the new GRUB2, this page is a good place to start.

How to create a "GRUB boot floppy"

If you have two (or more) hard drives on your system, you may prefer to install different linux distributions on separate hard drives. This allows for a very simple installation, at the expense of wasting some hard drive slots.

During the installation of the first distribution, choose to install the boot loader on the master boot record (MBR) of the default boot hard drive, so that your system will always boot by default (if no floppy is inserted), to the first distribution.

During the installation of the second (and subsequent) linux distribution, it is simplest to select NOT to install any boot loader, and then use the "GRUB boot floppy" described here to allow you to choose between the distributions by only modifying the contents of the menu.lst (or grub.conf) configuration file located on the floppy.

As long as you remember where the linux distributions are installed, this method overcomes the complexity of figuring out which hard drive is the default one, where the boot loader is installed, what file-system the boot loaders menu.lst file is contained in, whether all the distributions can actually mount that file-system to edit the menu.lst configuration file, and a host of other issues.

You always know that the boot loader and its menu.lst is on the floppy, and that the floppy is formatted with an ext2 file-system which all linux distributions understand, so changing the configuration is simply a matter of mounting the floppy and editing menu.lst.

So why would I need a "GRUB boot floppy"?

The "GRUB boot floppy", described here, allows you to choose which distribution to boot, without needing to alter anything about the boot loader installed on your default hard drive. That way, you always have the boot loader installed on the default hard drive as a fallback in the event your floppy disk wears out or gets corrupted. You can always go back to just booting the first distribution by simply removing the floppy disk, and letting the system boot from the default hard drive.

Consult the documentation for GRUB for a more in-depth discussion of GRUB. There's also Grub From the Ground Up by Steve Litt, and this guide for restoring grub.

The detailed steps to make the "GRUB boot floppy" are as follows. These steps were tested on a SuSE 8.2 system.

1. Find a Linux machine with the grub packages installed.

Boot up your system into any linux distribution that includes grub. For example, SuSE 8.2 includes GRUB.

2. First create a "Native GRUB boot floppy"

Let's create a "Native GRUB boot floppy" first, and use this to run grub, because although grub can run under linux, it much prefers to run on bare hardware. You should not see any errors like "Input/output error". If you do, start again with a new floppy.
      cd /usr/lib/grub
      dd if=stage1 of=/dev/fd0 bs=512 count=1
      dd if=stage2 of=/dev/fd0 bs=512 seek=1
The results for SuSE 8.2 should be as follows:
      # dd if=stage1 of=/dev/fd0 bs=512 count=1
      1+0 records in
      1+0 records out
      # dd if=stage2 of=/dev/fd0 bs=512 seek=1
      196+1 records in
      196+1 records out
For Debian, there is a convenient package called grub-disk which includes both a bootable floppy image and a bootable CD ISO image with grub configured in them. Install the grub-disk package, search for the name of the bootable floppy image file, and write it out to a new floppy using the following (thanks to Marcus Veit):
   apt-get update
   apt-get install grub-disk
   dpkg -L grub-disk|grep pc.ext2fs.gz
   zcat /usr/share/grub-disk/grub-0.95-i386-pc.ext2fs.gz|dd of=/dev/fd0 
When booting this floppy, you'll usually need to type the letter c to get to the grub command line, as the floppy image contains a sample menu already, which grub displays to offer the boot choices. Of course, if you need to run grub commands, then you need to first go to the grub command line using c.

3. Label your new Native GRUB boot floppy

Remove this newly-created "Native GRUB boot floppy", and keep it for later, after making a convenient label for it so that you can find it when you need it.

4. Making the real GRUB boot floppy

Take a second floppy disk. This will become your new "GRUB boot floppy". Format the floppy disk, using
      fdformat /dev/fd0h1440

5. Make the filesystem.

Create a file-system on the floppy disk, using:
      mke2fs -m 0 /dev/fd0

6. Mount the floppy.

Mount the filesystem of the floppy diskette on the mount point /media/floppy, using:
      mount -t ext2 /dev/fd0 /media/floppy

7. Copy the GRUB images.

You can find the GRUB images either in /boot/grub, or by using:
      rpm -qlf /usr/sbin/grub|egrep "stage1|stage2"
On SuSE 8.2, you would find them in /usr/lib/grub. Copy the GRUB images into the directory /media/floppy/boot/grub on the floppy disk. Usually only the files stage1, stage2 and menu.lst are necessary, but there's no harm in copying everything, e.g.:
      mkdir -p /media/floppy/boot/grub
      cp /usr/lib/grub/stage1         /media/floppy/boot/grub
      cp /usr/lib/grub/stage2         /media/floppy/boot/grub
      cp /usr/lib/grub/e2fs_stage1_5  /media/floppy/boot/grub

8. Customize your new boot menu.

Modify the /media/floppy/boot/grub/menu.lst to include menu entries for both of the distributions you have installed. In this example, United Linux was installed on the first hard drive, with both "/" and "/boot" on /dev/sda2 (hd0,1), (i.e. no separate "/boot" file-system, it was part of the "/" file-system, which was made as a reiserfs file-system), and RedHat was installed afterward, on the third hard drive, with "/" on /dev/sdc2, and "/boot" on /dev/sdc1 (hd2,0), so /media/floppy/boot/grub/menu.lst looks like this:

default 0
timeout 8

title United Linux, from (hd0,1) (via GRUB BOOT FLOPPY)
   kernel (hd0,1)/boot/vmlinuz root=/dev/sda2  apic
   initrd (hd0,1)/boot/initrd
title RedHat Linux, from (hd2,0) (via GRUB BOOT FLOPPY)
   kernel (hd2,0)/vmlinuz root=/dev/sdc2
   initrd (hd2,0)/initrd.img

9. Unmount the floppy.

Unmount the floppy, using:
      umount /media/floppy
Remove this floppy, this is your partially built "GRUB boot floppy".

10. Boot up into Native GRUB.

Shutdown the system, and reboot using the "Native GRUB boot floppy", created earlier in step 2. Eject the "Native GRUB boot floppy" once you get to the "grub>" prompt, and replace it with the "GRUB boot floppy".

11. Use Native GRUB to install GRUB.

Install grub into the MBR of the "GRUB boot floppy", using the following grub commands:
root (fd0)
setup (fd0)
quit
You should see something like the following:
grub> root (fd0)
  Filesystem type is ext2fs, using whole disk

grub> setup (fd0)
  Checking if "/boot/grub/stage1" exists... yes
  Checking if "/boot/grub/stage2" exists... yes
  Checking if "/boot/grub/e2fs_stage1_5" exists... yes
  Running "embed /boot/grub/e2fs_stage1_5 (fd0)"... failed (this is not fatal)
  Running "embed /boot/grub/e2fs_stage1_5 (fd0)"... failed (this is not fatal)
  Running "install /boot/grub/stage1 (fd0) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded
  Done.

grub>
quit

Note: Installing grub as described in this step will result in changes to the file /media/floppy/boot/grub/stage2 being made by grub.

12. Try it out.

Reboot the system using this newly-created "GRUB boot floppy", to make sure all distributions appear correctly in the menu, and that each of them can be booted by means of the "GRUB boot floppy" as desired.

Installing grub into the MBR of your default hard disk: "Native" method

Caution: Installing GRUB's stage1 in this manner will erase the normal boot-sector that may already be present on the default hard disk.

Boot the system into grub using the "Native GRUB boot floppy" created above.

Once started, GRUB will show the command-line interface. First, set the GRUB's root device to the partition containing the boot directory, e.g. like this:
     grub> root (hd0,1)

If you are not sure which partition actually holds this directory, use the command "find", like this:
     grub> find /boot/grub/stage1
This will search for the file name /boot/grub/stage1 and show the devices which contain the file.

Once you've set the root device correctly, run the command "setup":
     grub> setup (hd0)

This command will install the GRUB boot loader on the Master Boot Record (MBR) of the first drive. If you want to put GRUB into the boot sector of a partition instead of putting it in the MBR, specify the partition into which you want to install GRUB:
     grub> setup (hd0,1)

If you install GRUB into a partition or a drive other than the first one, you must chain-load GRUB from another boot loader.

Installing grub into the MBR of your default hard disk

The "Native" method described above is more likely to be successful, as it accesses the BIOS drive directly, but sometimes the following method can also work from Linux, so let's describe it.

To install grub onto hard disk, first make sure the file /boot/grub/device.map contains the correct correspondence from BIOS drive to unix drive for your machine, e.g.:
(hd0)   /dev/sdh
(fd0)   /dev/fd0
To install the GRUB boot loader on the Master Boot Record (MBR) of the first drive, just run:
grub-install '(hd0)'
And you should see the reassuring message:
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(hd0)   /dev/sdh
(fd0)   /dev/fd0

Reboot without your trusty "GRUB boot floppy" to check if it worked as expected, and if not reboot again with the "GRUB boot floppy" to try again...

Serial console with GRUB

Editing /boot/grub/grub.conf, you need to add the line:
  serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
and also append console=tty0 console=ttyS0,115200n8r to the kernel line, e.g.:
  kernel /vmlinuz ro root=/dev/hda6 console=tty0 console=ttyS0,115200n8r

Serial console with Xen and GRUB

If you want to use a serial console with Xen, then the syntax is a little different. You need to instead add the serial setting for com1 to the kernel line (where xen is booted from), as well as adding the usual console setting to the first module line, as follows:
  title Xen 2.0 / XenLinux 2.6
    kernel /boot/xen-2.0.gz dom0_mem=131072 com1=115200,8n1
    module /boot/vmlinuz-2.6-xen0 root=/dev/sda4 ro console=tty0 console=ttyS0,115200n8r
    module /boot/initrd-2.6-xen0.gz
Note that to specify the real Xen-enabled linux kernel (as opposed to the Xen virtual machine monitor, which goes on the GRUB kernel line), the module line is used. A second module line is used to specify the initial ramdisk for the Xen-enabled linux kernel. If the first module line doesn't contain the setting for console of ttyS0,115200n8r, then only the Xen virtual machine monitor will be able to use the serial console, whereas the way it's shown above the serial console will be shared with the Xen-enabled linux kernel.

Using the Command Line find Feature of GRUB

When booting up SuSE 9.0, to get out of the graphical boot menu into the regular grub boot menu, press the "Esc" key. In grub, press the key "e" to edit whichever grub boot entry you like. Note: you need to press "e" for each of the lines, i.e. you need to edit the kernel and initrd lines separately, before booting.

What if you are not sure which BIOS drive contains the bootable linux kernel? You can search for it using grub's commandline. To do this, you must know the full path (within the partition) of the file you are looking for, in this case we're looking for /boot/menu/menu.lst. Once you know this, go to the grub commandline by pressing the key "c". and enter:
  find /boot/grub/menu.lst
The reply from grub might look something like this:
  (fd0)
  (hd0,4)
  (hd2,0)

If you always make a symbolic link in /boot from vmlinuz and initrd to your actual vmlinuz and initrd, then you will always quickly be able to find them using grub's commandline find feature.

Using grub to boot Knoppix images.

First copy the contents of /boot of the Knoppix CD-ROM to a boot partition on your hard drive, for example "/boot.knoppix". This partition may be ext2/3, reiserfs or even a vfat partition, all of which are supported by grub.

Copy the /KNOPPIX directory from the Knoppix CD-ROM to the top level (root, "/") directory of the filesystem on any hard disk on your system. You may place it on any filesystem of type ext2/3, reiserfs or vfat, and it doesn't necessarily need to be placed in the "/boot.knoppix" directory.

Add the following to your /boot/grub/menu.lst:
 title           KNOPPIX
 root            (hd0,0)
 kernel  /boot.knoppix/vmlinuz 2 fromhd=/dev/hda4 lang=us
 initrd  /boot.knoppix/miniroot.gz
Note: The parameter "fromhd=" is used to specify the disk location of the filesystem where you previously copied the /KNOPPIX directory.

Some Last-resort GRUB tricks: Single-user mode

If the linux system doesn't boot up, there are still a few tricks you can use with GRUB to get it back into a usable shape, so that you can get back into the system to use it to figure out what is going wrong.

The first trick is to append the following to grub's kernel line (you may need to press "Esc" to leave the graphical boot screen, to get to the real grub command line), by using the e key to edit:
   init=/bin/bash
This will start a shell without starting any daemons or other stuff. It replaces the init process with a shell. If the system shutdown was clean, you should then be able to re-mount the root filesystem read-write, for example to reset a forgotten root password, using:
  mount -o remount,rw /
Sometimes, before you can edit system files after a hard reset of the machine, you have to run a filesystem check on the root filesystem, for example:
  /sbin/fsck -f -y /dev/hda1

The next trick is to check each daemon. To do this on a SuSE system, edit the file /etc/sysconfig/boot

Change the line:
  PROMPT_FOR_CONFIRM="no"
to:
  PROMPT_FOR_CONFIRM="yes"

This will cause the init sequence to then prompt you on the console about whether or not you want to run each of the init steps.

Using GRUB to boot up an elusive kernel

Let's say you boot up your machine, and nothing comes up. GRUB isn't found, or something has gone wrong with the boot block, or whatever. You know the kernel is still there, on some partition although you can't quite remember which. Well, if you know the exact filename of the kernel file you need to boot, you may well be much closer to getting the system back up than you think.
If you make a backup of your /boot/grub/menu.lst file after installation of your linux system, or write down the name of the kernel file in your notebook, it can help with this situation. You can also use filename completion in grub by pressing TAB whenever a filename is needed, and grub will prompt you with a list of possible choices. This works best if you remember whether you used a separate partition for /boot, of course. Otherwise, as a last resort, you may need to boot up the system again using a recovery CD or a live CD and have a look around to find out the filename.

In any case, once you know the name of the kernel file, then to boot that kernel, boot up the system from the "Native GRUB boot floppy" as described earlier, then ask grub to "find" which partition it is on, for example:

grub> find /boot/vmlinuz-2.4.27-2-386
grub> find /boot/initrd.img-2.4.27-2-386

Grub will show something like:

(hd0,0)

So now, to boot up linux, just type the following at the "grub>" prompt:

grub> root (hd0,0)
grub> kernel /boot/vmlinuz-2.4.27-2-386 root=/dev/hda1 ro
grub> initrd /boot/initrd.img-2.4.27-2-386
grub> boot