LJ Archive

One Key to Rule Them All: GRUB, USB and a Multiboot Environment

Adrian Hannah

Issue #211, November 2011

Do you have a spindle of CDs, each of which with a live environment you use for a specific purpose? Read this article to learn how to combine them all into one unified boot environment on a USB drive.

It's inevitable. If you work with Linux professionally, you will end up with a bevy of CDs or USB drives, each with their own live environment, each with a specific purpose. You likely have some haphazard system for keeping track of which device has what on it (my personal method was masking tape and pencil). But, there's no reason to keep doing this! Improvements in bootloaders (particularly GRUB) let you have live, persistent operating environments installed on USB drives as well as allowing for multiboot environments. Put this all together, and you get a single USB drive that replaces the gaggle of devices you used to have.

Setting Up GRUB on USB in Linux

Thanks to the Linux community's prolific use of GRUB as the default bootloader, installing GRUB to the Master Boot Record for a USB device is incredibly easy. Assume that you want to call your new volume “Multipass” and that your target device resides at /dev/sdb1. First, you need to create the filesystem:

sudo mkfs.vfat -n Multipass /dev/sdb1

Next, you need to mount the filesystem and install GRUB:

mount /dev/sdb1 /mnt/
grub-install --no-floppy --root-directory=/mnt /dev/sdb

Now you can add .cfg files to grub.d/ in order to add/edit/delete menu items to the boot menu or customize the boot menu.

Setting Up GRUB on USB in Windows

Installing GRUB on a USB device is markedly different in an environment that doesn't natively have GRUB utilities, but it isn't impossible. Tools like GRUB4DOS and WinGRUB are available that give you access to the same tools in Windows that are available in Linux. Basically, you need to find tools to initialize the drive as a bootable drive and install GRUB to the device. PeToUSB, GRUB4DOS and grubinst are the most widely used set of tools to accomplish this. PeToUSB uses a simple GUI interface to initialize the USB device as a bootable device. grubinst is a GUI installer that installs GRUB to the USB device. The only reason you need to download GRUB4DOS is because you need to copy “grldr” to the USB device. You can find more detailed instructions on how to use these tools on-line. But, as Windows installations are outside the purview of this publication, I digress.

Adding Distributions

Once you have GRUB set up, you need to add something to boot. Download your favorite live CD or app CD, and extract it using something like the GNOME Archive Manager. Do not extract this to your USB drive! Instead, extract it to a temporary location. Once you have performed this procedure several times, you will notice that almost all Linux distributions have a boot directory, and the files within this directory are the kernel image and vary from distribution to distribution. Then, rename the boot directory to something apropos to the distribution (for instance, “boot-ubuntu”), and copy it to the USB device. Aside from the boot folder, there typically is another folder in these ISOs that contains the boot image for the OS (for instance, BackTrack4's image is stored in a directory called bt4). Copy this folder to the USB device as well. You then need to add an entry in the configuration file so that this distribution will show up in the boot menu.

This is where a major schism occurs, and a little more background knowledge of GRUB is required. There are two versions of GRUB, initially referred to as GRUB and GRUB2, they now are called GRUB Legacy and GRUB, respectively (GRUB4DOS is a derivative of GRUB Legacy). There are a significant number of differences between the two, but the one that is important to us right now is that GRUB Legacy uses the menu.lst file for boot menu configuration, and GRUB uses grub.cfg. So depending on the source of the GRUB installation on your USB device, you will use a different configuration file.

Some distributions are distributed as a floppy disk image. Those are the best—all you have to do is copy the file to the root of the USB device and add a one-line entry to the config file.

Even though this takes time, you're better off testing each distribution after installing a new distribution. That way, if you find an error, it'll be easier to troubleshoot the problem. Trust me, installations can be finicky when you do things this way, and they can break for what seems like no good reason.

Adding a Menu Item in grub.cfg

At its most common and basic form, each menu entry will provide:

  1. A user-friendly title.

  2. The root filesystem.

  3. A kernel image.

  4. A boot image or initial ramdisk.

For example:

menuentry "Made Up Distro" { #user-friendly title
    set root=(hd0,1) #root filesystem
    linux /boot-madeup/vmlinuz0 #the kernel image
    initrd /madeup/initrd0.img #the boot image
}

Some distributions take some tweaking to get them to load properly. For instance, some live CDs need to be booted into 16-bit mode, and in that case, you would use linux16 and initrd16 instead. You can look in the GRUB manual on-line for all sorts of boot parameters and tweaks you can use on the menu item to make it work, but your best resource is the grub.cfg that was on the original ISO for the distribution. Some entries can become ridiculously complex in order to work right, like for Fedora:

linux /fedora1/isolinux/vmlinuz0 live_locale=en_US.UTF-8
↪live_keytable=us live_dir=/fedora1 root=UUID=A716-9810 
↪rootfstype=auto ro liveimg quiet rhgb 
↪rd_NO_LUKS rd_NO_MD noiswmd

This is the actual kernel image command from my own multipass device. It is long and tedious, but it works.

Adding a Menu Item to menu.lst

The menu.lst file, with regard to menu items, is quite similar to the grub.cfg entries. You still specify the user-friendly title, the root filesystem, and the kernel and boot images, but the syntax is a little different. An entry in menu.lst would look something like this:

title Made Up Distro
root (hd0,1)
kernel /boot-madeup/vmlinuz0
initrd /madeup/initrd0.img
boot

As with the grub.cfg entries, you can use many more commands than you can use in menu.lst, and you can make a lot of tweaks to make a nonfunctional entry suddenly work.

ISO Loopback

It all seems pretty daunting, no? Don't you wish there were a way to dump all your ISO files onto one disk and then mount them all? Your wish is granted! With GRUB2, we were introduced to the loopback boot option. This allows you to use GRUB to mount an ISO file and boot from it as if it were a physical piece of media. All you have to do for the menu entries is add a loopback command and then adjust the linux and initrd commands:

menuentry "Made Up Distro" { #user-friendly title
    set root=(hd0,1) #root filesystem
    loopback loop "/madeup.iso"
    linux (loop)/boot/vmlinuz0 #the kernel image
    initrd (loop)/initrd0.img #the boot image
}

GRUB then mounts the ISO file and boots accordingly. Note that you still may need to add some arguments to either command to get it to boot properly. Unfortunately, this doesn't work for all ISO files. If you can't get the loopback to work for an ISO, you have to load it the old-fashioned way as described above.

Customizing the Boot Menu

What good would a fancy tool like this be if you couldn't customize it to your liking? The default boot menu is white text on black background, which, let's face it, is boring. In your config file, you can specify a background image or color, text color, highlight color, alternate text for your menu entries, and the list goes on.

Set the Background Image

First, if you are using GRUB4DOS, the background picture has to be converted to 640x480 and 14-color, so you need to make sure that whatever you're using will look good under those constraints. GRUB2 has a bit more-advanced rendering capability, and it can handle JPG-, TGA- and PNG-formatted pictures as long as they are in RGB mode and not indexed mode.

The basic process for doing this is to scale and crop the image to your liking, limit the number of colors in the image palette to 14, save the image as an xpm file, and gzip it. For a more in-depth explanation of this process, I will use GIMP, although there are a number of other ways to do this.

After opening the image in GIMP, use a combination of scaling the image (Image→Scale Image) and the crop tool to make the image 640x480. To drop the number of palette colors in the image, click Image→Mode→Indexed, and choose “Generate optimum palette” with 14 colors. That's all there is to it. You can do other things to the image to make it look better in 14 colors:

  • Filters→Blur→Selective Gaussian Blur: this smooths out the image without losing detail.

  • Colors→Posterize: this turns subtle differences in color into a large field of a single color. This is done smoothly, which makes the image look better in 14 colors.

  • Colors→Levels→Auto: this increases the contrast of the image, lessening the number of colors used in the image.

  • Colors→Map→Gradient Map: maps the existing colors in your image into a gradient, essentially minimizing the colors used.

Once you've got your image the way you want it, save it as an XPM image file, then gzip the XPM file. You'll end up with a file named something like image.xpm.gz. Move this file to your USB device.

If you are running GRUB4DOS, look in menu.lst for a line something similar to this:

splashimage splash.xpm.gz

If you find it, replace the splash.xpm.gz with the path and filename of your file. Otherwise, add the line.

If you are running GRUB2, open grub.cfg and find a line that looks something like this:

GRUB_BACKGROUND=splash.xpm.gz

If it exists, replace the image name with the path and filename for your image. Otherwise, add the line, then run:

update-grub

Set the Menu and Highlight Color

You also can adjust the color of the menu text itself. You can adjust two separate values: the normal color (consisting of most of the text and the menu border) and the highlight color (the colors for the item currently selected in the menu list). Each of these values consists of two colors: the foreground and the background. Colors you can choose from include black, dark-gray, light-gray, white, brown, yellow, red, light-red, blue, light-blue, green, light-green, cyan, light-cyan, magenta and light-magenta. If black is chosen as the background color, it will show as transparent.

The command to adjust the colors in menu.lst for GRUB4DOS is color, followed by the normal color and then the highlight color. Specify the foreground and background colors by using a forward slash. For example:

color white/black white/blue

The above signifies white text on a transparent background, and the highlighted text is white on a blue background.

GRUB2 uses two variables in grub.cfg to accomplish the same thing. These variables are COLOR_NORMAL and COLOR_HIGHLIGHT. Again, use the forward slash to separate foreground color from background color:

COLOR_NORMAL="white/black"
COLOR_HIGHLIGHT="white/blue"

Change the Text Font

As far as I've been able to discern, you can change the font used in the menu only if you are using GRUB2. To accomplish this, you need to utilize one of the many nifty tools that come with grub: grub-mkfont. Assuming you already have the font and you know where the font file resides, you simply need to run grub-mkfont, and specify the location of the font file, the destination for the grub font file and the size you want the text to be in points. For example:

sudo grub-mkfont --output=/path/to/usb_device/comicsans.pf2 --size=14
/usr/share/fonts/comicsans.ttf

Then, in your grub.cfg file, add the variable GRUB_FONT and set it to the path and name of the grub font file you just created:

GRUB_FONT=/path/to/usb_device/comicsans.pf2

Applications to Automate the Process

Take everything I've taught you up to this point and throw it out the window! There are a number of different applications for all the major operating systems that easily will replicate the previously outlined procedure with little to no fuss. YUMI and SARDU are the top picks for generating a multipass in Windows, and MultiSystem is the tool of choice in Linux. Each of these applications has a handy GUI that walks you through adding all the images you want and customizing the menu to your heart's content.

I was first introduced to the concept of a multiboot USB device several years ago when the only way to set it up was manually with a lot of guessing and checking. I don't mind telling you, it was a royal pain to get anything working, let alone be elegant. As time goes by, utilities to help you set them up have emerged, and they've gotten better. What took me several hours to set up two years ago, took me only about 15 minutes this time around (and that includes the time to download the ISOs).

Adrian Hannah has spent the last 15 years bashing keyboards to make computers do what he tells them. He currently is working as a system administrator for the federal government. He is a jack of all trades and a master of none. Find out more at about.me/adrianhannah.

LJ Archive