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