AustinTek homepage | Linux Virtual Server Links | AZ_PROJ map server |

Howto make a Linux and Windows dual boot USB flash disk/drive

Joseph Mack

jmack (at) austintek (dot) com

22 Dec 2009


Table of Contents

1. assumptions
2. setup device.map
3. install grub to flash drive
4. boot to /dev/hda
5. grub error: "bad file or directory type"
6. boot to /dev/sda
7. booting windows
8. final menu.lst"

1. assumptions

The assumptions are

  • Your machine dual boots with grub and the grub files are in /boot. You want to be able to boot the machine from a usb flash drive as well.
  • The hard disk is /dev/hda, with Windows in hda1 and Linux / in hda3.
    fdisk -l /dev/hda
    
       Device Boot      Start         End      Blocks   Id  System
    /dev/hda1   *           1        1967    15799896    7  HPFS/NTFS
    /dev/hda2            3919        3950      257040   82  Linux swap / Solaris
    /dev/hda3            3951        4075     1004062+  83  Linux
    .
    .
    
  • The flash drive is seen by the OS as /dev/sda.
  • The flash drive transfers files between Linux and Windows machines, so needs both a FAT32 partition and an ext3 partition. If the first partition is ext3, Windows will ask if it can format it (and not look any further for Windows readable partitions). To keep Windows happy, on the flash drive make the first partition (/dev/sda1) FAT32 and make the other partition (say /dev/sda4) ext3.

2. setup device.map

You can put the grub files in either partition (here /dev/sda1, /dev/sda4) of your flash drive (but you won't be able to have symbolic links in the FAT32 partition). Mount the usb flash drive partition that will hold your grub files and copy your current /boot directory to it

/ # mount -t ext3 /dev/sda4 /mnt	#or mount -t vfat /dev/sda1 /mnt
/ # cd /mnt
/mnt # cp -auvp /boot .

Now run the machine's grub-install. You'll get an error message about a missing BIOS drive.

/mnt: # cd boot
/mnt/boot# grub-install --root-directory=/mnt --no-floppy '(hd0)'
/dev/sda1 does not have any corresponding BIOS drive.

I had to be straightened out here by the Knoppix USB Based FAQ. The problem is that /mnt/boot/grub/device.map is setup for the drives on your original machine, but doesn't know about the usb drive. Here's the fix.

/mnt/boot/grub# echo '(hd0) /dev/sda' > device.map

Following this instruction, the flash drive only knows about itself and won't go looking at the hard disk to boot.

3. install grub to flash drive

Install the boot tracks on the flash drive's mbr.

/mnt/boot/grub# grub-install --root-directory=/mnt --no-floppy '(hd0)'
Installation finished. No error reported.
This is the contents of the device map /mnt/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/sda

If you don't have a floppy disk and device.map has a floppy disk, and you omit --no-floppy, then grub-install will run for a long time (several minutes), spinning your hard disk, before installing the boot tracks.

The Linux kernels that boot the machine are on the internal hard disk (/dev/hda). I have copies of these kernels in /boot on the USB drive, in case something goes wrong.

4. boot to /dev/hda

Here's my menu.lst for booting to /dev/hda.

# /mnt/boot/grub/menu.lst 
default 0
timeout 5
fallback 0

color yellow/light-blue blink-red/green

#when the machine boots, the usb disk is (hd0) 
#the internal harddisk (/dev/hda) appears to the bios as (hd1)

title  linux-2.6.22.19 (APM)
kernel (hd1,2)/boot/bzImage-2.6.22.19 ro root=/dev/hda3

title slackware-13.0 root on /dev/hda
kernel (hd1,2)/boot/vmlinuz-huge-smp-2.6.29.6-smp ro root=/dev/hda3

title  memtest
kernel (hd1,2)/boot/memtest.bin
#---------------------------------

5. grub error: "bad file or directory type"

(This is error 2 in v0.97 and error 10 in v0.90.) The explanation for this error is

This error is returned if a file requested is not a regular file, but something like a symbolic link, directory, or FIFO.

If the partition type is correct (see below for showing partition types with grub) and you can read files on the partition when the disk is mounted on some other machine, then grub cannot read the filesystem. I got this when the disk to be booted had been formatted with a newer version of ext3 than grub on the flash disk knew about. I reformatted the target disk (the disk to be booted). You could rebuilt grub for your flash disk.

Note
Filesystems made by newer versions of ext[23] cannot be read by the previous ext2tools. It would be better in this case if new versions of extn was renumbered to ext4,5,6, making the incompatibility clearer to unsuspecting users.

6. boot to /dev/sda

The menu.lst above for booting to /dev/hda doesn't work if the harddisk is seen by the OS to be /dev/sda. Possibly you'll get a kernel panic with the kernel not being able to find/mount the root device. You told grub that the flash disk was /dev/sd0 and when the machine boots, it will look to the harddisk ((hd1,2)) to boot which is fine. After booting you told the OS to load root from /dev/sda3 which is on the flash drive. The cure for this is to remap the BIOS names for the drives, so that after booting, the OS is told that the harddisk is /dev/sda.

Here's the menu.lst lines to mount root from /dev/sda.

title slackware-13.0 root on /dev/sda
kernel (hd1,2)/boot/vmlinuz-huge-smp-2.6.29.6-smp ro root=/dev/sda3
map (hd0) (hd1)
map (hd1) (hd0)

You can swap the two remapping lines and mounting root still works.
<programlisting><![CDATA[
.
.
map (hd1) (hd0)
map (hd0) (hd1)
.
.

7. booting windows

You need to remap the drives (flash disk and hard disk) so that windows thinks it's booting from the first drive on the machine. Here's the menu.lst section.

# For booting Windows NT or Windows95
title wxp
#mount /dev/hda after booting
root (hd1,0)
makeactive
#windows is no longer on (hd0), it's on (hd1)
#tell windows that it's running on (hd0)
#map hd1 back to hd0
map (hd0) (hd1)
map (hd1) (hd0)
chainloader +1

What happens with Windows, if you don't remap the BIOS drives? This will be your menu.lst

.
.
title wxp
root (hd1,0)
makeactive
chainloader +1
.
.

You are asking grub to do something with (hd1,0) (the BIOS name for your internal hard disk). On boot you'll get this error message

Filesystem type unknown, partition type 0x7

To see where this comes from, at the grub prompt enter root (hd1, and then hit tab (\t)

grub edit> root (hd1,
 Possible partitions are:
   Partition num: 0, Filesystem type unknown, partition type 0x7
   Partition num: 1, Filesystem type unknown, partition type 0x82
   Partition num: 2, Filesystem type is ext2fs, partition type 0x83
   Partition num: 4, Filesystem type is ext2fs, partition type 0x83
   Partition num: 5, Filesystem type is ext2fs, partition type 0x83

The first partition is NTFS and has an NTFS filesystem. The NTFS filesystem is not known to grub.

For comparison here's what grub sees on your flash drive (hd0) (hit the tab key after entering the ",")

grub edit> root (hd0,
 Possible partitions are:
   Partition num: 0, Filesystem type is fat, partition type 0xb
   Partition num: 3, Filesystem type is ext2fs, partition type 0x83

If you swap the BIOS drive numbers with map at the grub command line,

grub> map (hd0) (hd1)

grub> map (hd1) (hd0)

grub> root (hd0,
 Possible partitions are:
   Partition num: 0, Filesystem type is fat, partition type 0xb
   Partition num: 3, Filesystem type is ext2fs, partition type 0x83

grub still sees (hd0) as the flash drive and (hd1) as the internal drive, so the mapping apparently only affects WinXP when it's booted.

8. final menu.lst"

# /mnt/boot/grub/menu.lst 
default 0
timeout 5
fallback 0

color yellow/light-blue blink-red/green

#when the machine boots, the usb disk is (hd0) 
#the internal harddisk (/dev/hda) appears to the bios as (hd1)

title  linux-2.6.22.19 (APM)
kernel (hd1,2)/boot/bzImage-2.6.22.19 ro root=/dev/hda3

title slackware-13.0 root on /dev/hda
kernel (hd1,2)/boot/vmlinuz-huge-smp-2.6.29.6-smp ro root=/dev/hda3

title slackware-13.0 root on /dev/sda
kernel (hd1,2)/boot/vmlinuz-huge-smp-2.6.29.6-smp ro root=/dev/sda3
map (hd0) (hd1)
map (hd1) (hd0)

title  memtest
kernel (hd1,2)/boot/memtest.bin

# For booting Windows NT or Windows95
title wxp
#mount /dev/hda after booting
root (hd1,0)
makeactive
#windows is no longer on (hd0), it's on (hd1)
#tell windows that it's running on (hd0)
#map hd1 back to hd0
map (hd0) (hd1)
map (hd1) (hd0)
chainloader +1
#---------------------------------
AustinTek homepage | Linux Virtual Server Links | AZ_PROJ map server |