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

29 Mar 2015


Table of Contents

1. assumptions: hard disk at /dev/hda
2. setup device.map
3. install grub to flash drive
4. boot from hard disk at /dev/hda
5. grub error: "bad file or directory type"
6. applications use the MBR to store data
7. boot from flash disk at /dev/sda
8. booting windows
9. menu.lst for flash key, hard disk=/dev/hda
10. hard disk is /dev/sda
11. menu.lst for flash key, hard disk=/dev/sda
12. Recovery floppy disk

1. assumptions: hard disk at /dev/hda

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.
Note
How you do this depends on whether your hard disk is /dev/hda or /dev/sda. There is an extra section below for machines with the hard disk at /dev/sda.

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 .

In the `grub-install` line below

  • --root-directory is where the directory boot will be updated
  • --no-floppy in case you don't have a floppy disk, otherwise this command will take a long time to time out.
  • (hd1) is the BIOS name for the disk whose boot partition you want updated. If you have (hd0) here, the boot sector on your hard disk will be updated and you might wind up with an Error 21 next time you boot off the hard disk.

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

/mnt# grub-install --root-directory=/mnt --no-floppy '(hd1)'
/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 hard disk, but doesn't know about the usb drive. Here's the fix.

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

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 '(hd1)'
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'.

(hd1) /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 from hard disk at /dev/hda

Here's my menu.lst for booting from /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 hard disk (/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.

GRUB "Error 2" May Mean Incompatible stage1.5, stage2, and ext2 (http://www.plunk.org/~grantham/cgi-bin/blog.cgi?id=00018)

6. applications use the MBR to store data

Only the first block of the MBR is part of the boot specification. With the first block of the first partition now starting at the next cylinder (track) at block 63 (rather than the next block in the 0th cylinder), there are 62 blocks unused in the first cyclinder. The grub stage1_5 files needed to boot off file systems other than ext2, start at sector 9.

When I first got my Thinkpad X60, it would loose the boot information every day or so. I would get the GRUB> prompt and the machine wouldn't boot. Booting off a CD showed that my Windows and Linux partitions were just fine and I could restore the boot files by rerunning grub-install. I had a cronjob do an md5sum on the first 63 sectors every hour, to find that the first 63 sectors were being changed just before the machine lost its ability to boot.

Some Windows programs are supposed to use the unused 62 sectors to store information that the user can't scrub (license information etc). However I would loose the boot information just using Linux. It turns out that some drivers write to the boot cylinder. See the following forum posts, http://forums.gentoo.org/viewtopic-p-3217132.html, http://forums.gentoo.org/viewtopic-p-3377762.html, http://forums.gentoo.org/viewtopic-p-3388822.html.

The problem with Highpoint + GRUB is that the Highpoint BIOS stores its metadata in sector 9 of each harddrive. Normally this area is unused, so GRUB puts its stage1.5 file in that area too.

Since GRUB's stage1.5 is optional, the workaround is simple : don't use it :)

Code:
# cd /boot/grub
# rm *stage1_5
# grub
grub> root (hd0,0)	#or wherever you boot from, for me this is (hd0,2)
grub> setup (hd0)
grub> quit

I assume that this means optional if booting off an ext2 filesystem.

7. boot from flash disk at /dev/sda

The menu.lst above for booting from /dev/hda doesn't work if the hard disk 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 hard disk ((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 hard disk 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.
.
.
map (hd1) (hd0)
map (hd0) (hd1)
.
.

8. 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.

9. menu.lst for flash key, hard disk=/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 hard disk (/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
#---------------------------------

10. hard disk is /dev/sda

With the hard disk at /dev/sda, when you do setup the flash disk is at /dev/sdb. When booting from the flash disk, the device names are reversed.

At setup, assuming your flashkey is /dev/sdb, then after mounting the flashkey at /mnt, you need to change device.map.

/ # mount -t ext3 /dev/sdb4 /mnt
/ # cd /mnt
/mnt # cat boot/grub/device.map
(hd1)   /dev/sdb

The names in device.map are those at setup time, rather than at boot time. If you already have another usb device as /dev/sdb and the flashkey is /dev/sdc, then device.map will be (hd2) /dev/sdc.

/mnt # cat boot/grub/device.map
(hd2)   /dev/sdc

If the device name for your flashkey has been renamed by udev rules to say /dev/pny and you try the likely entry

/mnt # cat boot/grub/device.map
(hd2)   /dev/pny

then grub-install won't recognise /dev/pny as a BIOS device. I assume that grub-install is looking for a device name like /dev/sd?, but I don't know.

Here's how you run grub-install

/ # mount -t ext3 /dev/sdb4 /mnt
/ # cd /mnt
/mnt # cat boot/grub/device.map
(hd1)   /dev/sdb
/mnt # grub-install --root-directory=/mnt '(hd1)'
Installation finished. No error reported.
This is the contents of the device map /mars/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'.

(hd1)   /dev/sdb

If you've been plugging and unplugging flash drives, your machine may be confused as to the BIOS names of the drives and you may find your flashkey is no longer recognised as a BIOS drive. Just reboot your machine and try again.

One problem with running grub-install is that errors are not sent to the screen. You will get the final error message only which may not tell you the real problem. If there are errors you should run grub from the command line. Here's the procedure from Grub Installation for CentOS 5 and 6 (Grub Installation for CentOS 5 and 6).

[root@localhost ~]# grub
Probing devices to guess BIOS drives. This may take a long time.

    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]

grub> find /boot/grub/stage1
 (hd0,5)
 (hd0,9)

grub> root (hd0,5)
 Filesystem type is ext2fs, partition type 0x83

grub> setup (hd0)
 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 (hd0)"...  15 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p
(hd0,5)/boot/grub/stage2
/boot/grub/grub.conf"... succeeded
Done.

grub> quit

11. menu.lst for flash key, hard disk=/dev/sda

Here's menu.lst for my laptop with its hard disk at /dev/sda

# grub.conf: Dec 2010
default 0
timeout 5
fallback 1
color yellow/light-blue blink-red/green

#usb key in slot is (hd0) to bios
#making hard disk (normally seen as /dev/sda) hd1

title linux-2.6.35.5 on 3rd partition on hard disk, boot from usb key
kernel (hd1,2)/boot/bzImage-2.6.35.5 ro root=/dev/sda3 

title linux-2.6.35.5 on 4th partition on usb key, boot from usb key
kernel (hd0,3)/boot/bzImage-2.6.35.5 ro=/dev/sda3 

title memtest on hard disk, boot from usb key
kernel (hd1,2)/boot/memtest.bin

title winxp, boot from usb key
#for windows you have to fool it into thinking it's on the first disk
#mount /dev/sda1 after booting
root (hd1,0)
#after booting windows is no longer on (hd0), it's on (hd1)
#tell windows that it's running on (hd0)
map (hd0) (hd1)
map (hd1) (hd0)
makeactive
chainloader +1
#---------------------------------

12. Recovery floppy disk

Fir making bootable floppies see Linux Recovery and Boot Disk Creation

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