GRUB on USB

grub.png

I was recently looking at my development system and wanted to load Windows as a boot option to a system primarily running Linux.  This got me to thinking.  What if I did something that corrupted or overwrote the boot sector on my hard drive?  What if I could no longer boot into Linux as I had intended?  What if I just want to have an entire Linux installation on my USB drive?  Enter GRUB, a Linux boot loader.

Read more… 

Installation

Introduction 

The GRand Unified Boot loader, or GRUB, has all but replaced LInux
LOader, or LILO as the default boot loader for most Linux distributions
today.  The boot loader is what hands off control of the system from
BIOS Power On Self Test, or POST, to the Operating System.  In this guide, we will be creating a boot loader on a USB flash drive that loads Linux kernels that reside on your primary hard drive.  Of course you are free to add whatever
utilities or Operating Systems that you would like and have licenses for.  Some ideas
would be virus scanners or system utilities.  It is also possible to
load an entire operating system on the flash drive, but that is outside
the scope of this guide (but might be seen in the future).

This guide assumes that you have a Linux distribution loaded on your
system already with GRUB as the boot loader.  There are probably other
ways to get GRUB onto your USB flash drive but they will not be covered
in this guide.  Also, installation of a Linux OS will not
be covered, but you can follow John’s great CentOS installation guide to get to this point.

 

The Parts 

So lets get started.  Here’s what you will need:

  • USB flash drive
  • A system that can boot from USB
  • A system with Linux loaded using GRUB
  • some time
  • this guide

 

Finding The USB Flash Drive 

The first thing that you will need to do is boot into Linux as you
would normally.  At this point, you should connect the USB flash drive
if it is not already connected.  On my system, the USB flash drive
itself showed up as /dev/sdc with the single partition under /dev/sdc1.  It shows up as /dev/sdc because my other two hard drives are /dev/sda and /dev/sdb.  When the drive is inserted into the USB port, the data itself is mounted under /media/disk.  The directory name may be different for your system, but will likely be found under /media/<something>.  To find out for certain where your drive is mounted use the following command:


$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1               101086     19138     76729  20% /boot
/dev/sdb1             57483476   4784692  49731644   9% /
/dev/sdc1                63838       234     63604   1% /media/disk

This shows that /dev/sdc1 is 63,838 1k-blocks in size (64MB) and is mounted at /media/disk.  The commands in this guide assume that the drive is mounted at /media/disk from now on.

If the drive does not mount automatically, you can accomplish this by running the following commands:


$ mkdir /media/disk
$ mount /dev/sdc1 /media/disk 

The first command creates the /media/disk directory and the second command mounts the drive.  This guide will assume that it is mounted under /media/disk
Also note that all commands beginning with $ are issued by the regular
user, while commands starting with # are issued by root.  

 

USB Flash Drive Files And Directories 

The next step is to create the directory structure on the USB flash
drive and copy the needed files to it.  On my installation, the Linux
kernels and images under /boot and the GRUB files under /boot/grub
So lets make the necessary directories on our drive.  Note that you
will need to change the directory name to match the path to your USB
drive.  Also, you can create a different directory structure but you
will have to make sure that the correct path is used later on for files
like menu.lst.  For ease of use, I suggest using the indicated file
structure.  It is also important later to know that on my installation, the /boot directory is on a separate partition from the / directory.

$ mkdir /media/disk/boot
$ mkdir /media/disk/boot/grub

Now that we have that done, lets copy over the files that we need.  In
order to copy over grub.conf and menu.lst, you will need to be root.

$ su –
Password:
# cp /boot/grub/* /media/disk/boot/grub/

The su –
command changes you to SuperUser, or root, so that you can copy the
necessary files.  The next command does the actual copying.  Again, if
you used a different directory structure or your USB flash drive is
mounted at a different location, you will have to adjust all of the
commands accordingly.

 

Installation 

Now that you have the necessary files in place it’s time to install
GRUB into the Master Boot Record of the USB flash drive.  First let’s
make sure we’re loading GRUB onto the the correct drive.

# grub
grub> find /boot/grub/stage1
 (hd2,0)
grub> find /grub/stage1
 (hd0,0)

As stated earlier, in my installation, the /boot directory is
on its own partition.  This is what causes (hd0,0) to show up under
the second find command while (hd2,0) shows up under the first find command.  If the /boot
directory were included in the root (/) partition then it would have
been included in the first find command.  So enough confusion.  (hd2,0)
means that the /boot/grub/stage1 file is located on the first partition
of the third hard drive (numbering starts at 0).  In this case this is
referring to the main partition of the USB flash drive.  (hd0,0) is
referring to the /boot partition on my main hard drive.

So now we know that we want to load GRUB on (hd2,0).  There are three basic commands needed to do this: root, setup and quit.

grub> root (hd2,0)
 Filesystem type is fat, partition is 0x6
grub> setup (hd2)
 Checking if "/boot/grub/stage1" exists… yes
 Checking if "/boot/grub/stage2" exists… yes
 Checking if "/boot/grub/fat_stage1_5" exists… yes
 Running "embed /boot/grub/fat_stage1_5 (hd2)"…  16 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd2) (hd2)1+16 p (hd2,0)/boot/grub/stage2
/boot/grub/grub.conf"… succeeded
Done.
grub> quit

The first command, root (hd2,0) , sets the "root
device" in GRUB to the partition on the USB flash drive containing the boot directory.  In our
example, this is (hd2,0) meaning it is the first partition on the third
"hard drive", or sdc1.  The setup (hd2)
command installs the GRUB boot loader into the Master Boot Record (MBR)
of the drive.  If you do not want it loaded in the MBR but would
instead like it in a specific partition, you can use the command setup (hd2,0),
which will load it into the first partition (in that example).  There
is a note in the GRUB documentation stating that if you load the GRUB
boot loader into a partition instead of the MBR, you must chain-load
GRUB from another boot loader, meaning that you have to boot up with
some other boot loader in the MBR and tell it to load the GRUB boot loader from there.  That is
outside the scope of this guide.

Configuration

Configuration

So now we have GRUB installed on our USB flash drive.  What’s next?  There are two options at this point.  You can either tell the GRUB installation on your flash drive to load kernels that are installed elsewhere, such as on the original hard drive, or you can copy the kernel and initialization files to the USB flash drive and boot them locally.  We are going to boot them directly from the hard drive for two reasons: 1) it will save space on the flash drive allowing you to add other applications to boot, and 2) each time you install a new kernel on your system you will not have to copy it to the USB drive, you will just need to update the menu.lst file which will be demonstrated shortly.

 

Drive Ordering And Other Stuff 

In just a moment, we will set GRUB up to load the kernels that are located on our hard drive.  But first, we are going to play a little game with GRUB to change the drive ordering.  This is needed because if you change the boot order
in the BIOS to include the USB flash drive before the normal hard
drive, then it changes the order of the drives as far as GRUB and Linux see them also.  In my case, in a standard boot from the hard drive, my drive order is:

  • Main OS boot drive: (hd0)
  • OS data drive: (hd1)
  • USB flash drive: (hd2)

Now, when booting from the USB drive, you must change the order in the BIOS to include the USB drive first, so the order becomes:

  • USB flash drive: (hd0)
  • Main OS boot drive: (hd1)
  • OS data drive: (hd2) 

In order to keep things simple,  we will use the map command to change the order back to what it was if we weren’t booting from the USB drive.  To do this, open up the /media/disk/boot/grub/menu.lst file in your favorite text editor.  Before making any modifications, my menu.lst file looks like: 

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sdb1
#          initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora (2.6.24.4-64.fc8)
    root (hd0,0)
    kernel /vmlinuz-2.6.24.4-64.fc8 ro root=/dev/sdb1 quiet
    initrd /initrd-2.6.24.4-64.fc8.img
title Fedora (2.6.24.3-50.fc8)
    root (hd0,0)
    kernel /vmlinuz-2.6.24.3-50.fc8 ro root=/dev/sdb1 quiet
    initrd /initrd-2.6.24.3-50.fc8.img

On my system, the original /boot partition was located on hard drive 0, partition 0 (hd0,0).  Since we are booting off of the USB flash drive now, the drive order will change to what is mentioned above.  We will add the map command to change the order back again.  Also note that we needed to modify the kernel and initrd lines to include /boot at the beginning of the first parameter since the /boot directory is not in its own partition on the USB flash drive.  The end result should look like this:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sdb1
#          initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora (2.6.24.4-64.fc8)
    map (hd2) (hd0)
    map (hd0) (hd1)
    map (hd1) (hd2)
    root (hd0,0)
    kernel /boot/vmlinuz-2.6.24.4-64.fc8 ro root=/dev/sdb1 quiet
    initrd /boot/initrd-2.6.24.4-64.fc8.img
title Fedora (2.6.24.3-50.fc8)
    map (hd2) (hd0)
    map (hd0) (hd1)
    map (hd1) (hd2)
    root (hd0,0)
    kernel /vmlinuz-2.6.24.3-50.fc8 ro root=/dev/sdb1 quiet
    initrd /initrd-2.6.24.3-50.fc8.img

 

Testing 

So now that we have things setup the way that we want, let’s try it out.  At this point, you will need to reboot your system.  While it is booting up, you will need to enter the BIOS Setup Screen and change the boot order of the drives.  This is generally found under an Advanced BIOS setup screen.  Add USB-HDD or similar before the regular booting hard drive.  In my case, the order is CDROM, USB-HDD, hard drive.  Once this change is made, save the changes and let your system boot.  If all goes well, your USB flash drive will boot the system as though it were booting directly from the main hard drive.  If you want to be 100% certain that it is booting from the USB flash drive and not the hard drive, you can remove the hard drive from the boot order list.  I needed to do this the first time because the boot loader screen on the USB drive looked identical to the original so I had no idea that it was working correctly.  Once you have tested this, add the hard drive back to the boot sequence.  Now, whether you have the USB drive attached or not, you will be able to boot your system properly.

 

The End 

Congratulations, you’re done.  You have now created a backup drive to boot your computer in case something were to happen to your main boot setup.  Later, we will expand on this setup with more interesting uses.