USB Multibooting


I recently wanted to add multiboot support to my usb disk-on-key. I mainly use it for casual file transfers/play music on my car, but I also got BackTrack installed on it. From time to time I get to use it on a frined’s computer. BackTrack is one of many “live cd” operating systems, meaning you can boot it directly from cd drive/usb thumbdrive without affecting your hard disk. When you finish you just eject the cd/thumbdrive, reboot and everything would go back to normal as if nothing happened.

Live operating systems are very useful in many cases, usually when you want to perform some operations that you can’t or don’t want to do within your normal operating system, such as virus cleaning (if you’re infected and the virus killed your antivirus), hard disk backups, computer forensics, security assessment, files access, resetting your password, hardware problems diagnosis, checking if your hardware is supported by new operating system, etc…

Multibooting means to have the ability to boot more than operating systems. Unfortunately, most “live” operating system makers just provide you with image file (iso) you can burn to cd/dvd. At most, they give instructions how to install to usb thumbdrive, instructions that usually involve formatting it and even if not, you would still be able to boot only the last installed operating system (if you install more than one).

The method I’m going to present is inspired by pendrivelinux.com guide. They made windows utility to get the job done, but you only get the final result without understanding how it works or customizing it. This post is a step by step guide to make multiboot-able usb thumbdrive from scratch using Linux, plus you get to understand how it works, plus customize it, plus you don’t have to use physical drive as the whole thing can be emulated (very useful for testing). If you do it on physical drive make sure to backup your data before !!! Everything worked out of the box with my Ubuntu 9.10. If you have problems with other Linux distros post as comment and I’d try to help.

We would use grub4dos as bootloader. Download it from here. For this tutorial I’m going to use emulated usb thumbdrive, with it’s data back-stored as file named “usb.dsk”, so whenever I do something with this file, if you do it with real usb thumbdrive, the corresponding file is the one representing your thumbdrive such as /dev/sdd (you can figure it out with df -h command). Alright, let’s get dirty.

Creating the emulation file (skip if you use physical device)
We just need to create empty file at the size we want. It can be done with “dd” command. dd works by default with blocks of 512 bytes so it explains the following numbers (you can use any size, here are 2GB and 4GB examples):

4GB file creation:
# dd if=/dev/zero count=7892040 of=usb.dsk

2GB file creation:
# dd if=/dev/zero count=4029440 of=usb.dsk

Partitioning the emulated/physical device
If you use physical device and you don’t want to repartition/format it, the only requirement is to have FAT partition. You can check it with “fdisk -l” on your device file for example “sudo fdisk -l /dev/sdd”. Otherwise, keep reading this section (don’t forget to replace usb.dsk with your device file whenever specified. You may also need to run everything with sudo).

We need to partition our newly created file:
# fdisk usb.dsk

Ignore “you must set” warnings if you get any. fdisk command needs to know the physical structure of our emulated device, so we must tell it manually (if you use physical device ignore this). As I had no idea what structure I want, I just copied it from existing devices I own. 4GB device: sectors=62, heads=125, cylinders=1018. 2GB device: sectors=63, heads=255, cylinders=250. I think those numbers doesn’t really make any difference.

To tell fdisk the structure (this is for 2GB file but you can change the numbers):

Command (m for help): x

Expert command (m for help): s
Number of sectors (1-63, default 63): 63
Warning: setting sector offset for DOS compatiblity

Expert command (m for help): h
Number of heads (1-256, default 255): 255

Expert command (m for help): c
Number of cylinders (1-1048576): 250

Expert command (m for help): r

Command (m for help):

Now that device structure is set, use “p” to print the current partition table. The output should look like this (disk identifier may change):

Command (m for help): p

Disk usb.dsk: 0 MB, 0 bytes
255 heads, 63 sectors/track, 250 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x1194fc93

Device Boot      Start         End      Blocks   Id  System

Command (m for help):

If any partitions are shown, delete them with “d”. Make sure you don’t need the data already there as it will be deleted! Now we need to create new bootable FAT partition and we’re done. Just follow my commands (once again, numbers are for 2GB, you can use other numbers, as specified before):

Command (m for help): n
Command action
e   extended
p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-250, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-250, default 250): 250

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))

Command (m for help): a
Partition number (1-4): 1

Command (m for help): w
The partition table has been altered!

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.

If everything went smooth, you now have one FAT type partition at the size of your device.

Installing GRUB4DOS to Master Boot Record

To install grub4dos just run bootlace.com <device name> from where you extracted the zip archive:
# grub4dos-0.4.4/bootlace.com usb.dsk

Output should look like:

Disk geometry calculated according to the partition table:

Sectors per track = 63, Number of heads = 255

Success.

Formatting the device

If you use physical device skip to the last command in this paragraph (“Creating the FAT filesystem”). To format the partition (create new FAT filesystem on it) we first need to calculate it’s offset in our file. It is located on the second track. The number of sectors per track is what we defined before (2GB: 63, 4GB: 62) and number of bytes per sector is 512, meaning we need to skip  512 x 63 = 32256 bytes (in 2GB case).

Setting up the loop device with correct offset (2GB: 32256, 4GB: 31744):
# sudo losetup -o 32256 /dev/loop0 usb.dsk

Creating the FAT filesystem (for physical device use your partition filename such as /dev/sdd1, sdd’s first partition):
# sudo mkfs -t vfat /dev/loop0

Ignore the warnings about floppy size if you get any.

Copying necessary files

First we need to mount the filesystem (for physical device use your partition filename):
# sudo mkdir /mnt/usbdevice
# sudo mount -o uid=`id -u` /dev/loop0 /mnt/usbdevice

Copy “grldr” from grub4dos extracted archive:
# cp grub4dos-0.4.4/grldr /mnt/usbdevice

We almost finished. Your device is now bootable and boots grub4dos. We just need to configure the boot menu. Configuration file is “menu.lst”. It must be placed at the root directory of your device. You can either start with the sample file from grub4dos or use mine:

default 0
timeout 30
splashimage=(hd0,0)/splash.xpm.gz
foreground=d2d1d0
background=537ba7

title Ubuntu 10.04 64bit
find –set-root /ubuntu-10.04-desktop-amd64.iso
map /ubuntu-10.04-desktop-amd64.iso (0xff)
map –hook
root (0xff)
kernel /casper/vmlinuz file=/cdrom/preseed/ubuntu.seed boot=casper persistent iso-scan/filename=/ubuntu-10.04-desktop-amd64.iso splash
initrd /casper/initrd.lz

title Ultimate Boot CD 4.11
find –set-root /ubcd411.iso
map /ubcd411.iso (hd32)
map –hook
chainloader (hd32)

In this example I only have two live operating systems: Ubuntu 10.04 64bit and Ultimate Boot CD 4.11. All the files specified should be on root directory of your device. You can find the splash image I made here, ubcd411.iso here, ubuntu-10.04-desktop-amd64.iso here.

Basically, you can use every bootable iso file you want. However, some customization might be required as you can see that the two entries aren’t identical. For better understanding of grub4dos “map” command you can use this guide. I tried using the same method (load directly from iso file) for BackTrack3, but it didn’t work. I ended up extracting BT3 directory from bt3-final.iso and put it on the root directory. I also extracted “boot” directory and put it inside BT3 directory. I then added this entry to menu.lst:

title Backtrack 3.0
root (hd0,0)
kernel /bt3/boot/vmlinuz vga=0x317 initrd=/bt3/boot/initrd.gz ramdisk_size=6666 root=/dev/ram0 rw
initrd /bt3/boot/initrd.gz

It worked. The boot params specify to load it as frame buffer console (the way I like it). Anyhow, you can get ideas for many more interesting live operating systems you can use from pendrivelinux.com, their menu.lst and splash image can be found in their source archive, MultiBootISOs-Src.zip.

Finishing up

Congrats! everything is done. Let’s close everything we opened:
# sudo umount /mnt/usbdevice
# sudo losetup -d /dev/loop0

If you want to emulate real usb device using your usb.dsk use:
# sudo modprobe g_file_storage file=usb.dsk

Wait couple of seconds and it should be recognized. To stop:
# sudo modprobe -r g_file_storage

You can also use the same file as raw hard disk with kvm. (If you don’t know how to use kvm/qemu it’s definitely not the place to explain):
# qemu-system-x86_64 -m 512 -hda usb.dsk

Pretty cool ah ?


4 responses to “USB Multibooting”

  1. Hi, tried your guide, and 1st issue: find -set-root, should be ‘find –set-root’, and 2nd issue: what is 0xff ? I get an error on the first map line.

  2. @Sal Aguinaga
    I am wrong about the first issue. Your listing is correct, but the 2nd still stands. I tried: map (hd0,0)/ubuntuxxxxx.iso and it also doesn’t work.

    • First issue: it is indeed double hyphens but WordPress makes it look like one. Thanks for the note.

      Second issue: 0xff can be used instead of hd32 as described in GRUB4DOS README.
      For more information on using GRUB4DOS with .iso files check out this guide.

      Anyhow for Ubuntu you should probably use (taken from Pendrivelinux.com):

      title Ubuntu 10.10 (GNOME Desktop x86)
      find –set-root /ubuntu-10.10-desktop-i386.iso
      map /ubuntu-10.10-desktop-i386.iso (0xff)
      map –hook
      root (0xff)
      kernel /casper/vmlinuz file=/cdrom/preseed/ubuntu.seed boot=casper persistent iso-scan/filename=/ubuntu-10.10-desktop-i386.iso splash
      initrd /casper/initrd.lz