Booting (Red Hat) Fedora Core 2 Linux off of an USB HDD drive.

Update:  Nov 28, 2004 - Please see this site http://www.simonf.com/usb authored by Simon Ilyushchenko regarding Fedora Core 3.  Apparently there have been some changes regarding loopback device support and using cpio instead.   Please read Simon's information regarding this.

95 % of this document is from http://www.simonf.com/usb authored by Simon Ilyushchenko.  Simon's document is instructions for Redhat 9.0.   Many thanks to his hard work and well written instructions.  5% is my work in modifying Simon's instructions to work for Fedora Core 2.

Hardware: IBM R40 ThinkPad laptop.  1400 X 1050 pixel LCD display.  External 40GB USB 2.0 HDD.

First you need to install Linux.  To avoid the possibility of messing up the internal HDD (which contains my Windows XP image), I removed the internal HDD drive and did not put it back into the laptop until the installation was complete.  Remove one screw and the whole internal HDD slides right out.

You must use the "linux expert" mode to in order for the installer to detect your USB hard drive.
I had a 40GB drive, which I partitioned manually using Druid as follows:  102MB boot (sda1), 30GB root (sda2), 4GB swap (sda3), and 4GB VFAT (sda5)  (sda4 is the extended partition).  I highly recommend making a VFAT partition.  This has become a handy way of transferring files back and forth between Linux and Windows XP.

After the initial installation Linux will attempt to boot.  But instead you will get a Panic error due to the boot image having no drivers loaded for USB.

Double check that your BIOS is set up to boot from USB HDD before the internal HDD (or remove the internal HDD).

Boot the system using the first installation CD, using "linux rescue" mode.

Mount these partions manually and then change root to the hard disk's filesystem.

mount /dev/sda2 /mnt/source
mount /dev/sda1 /mnt/source/boot
chroot /mnt/source

You'll need to create a custom initrd image. Take your current image from /boot (see /etc/grub.conf for the exact name). In my case the exact name was "initrd-2.6.5-1.358.img".

cp /boot/initrd-2.6.5-1.358.img /tmp/initrd.gz
UnZIP the image.
gunzip /tmp/initrd.gz
Make a temporary directory to view the image with.
mkdir /tmp/a

Now mount the directory to view the contents of the image.

mount -o loop /tmp/initrd /tmp/a

The file /tmp/a/linuxrc is the script that runs before the root partition is mounted. We need to make sure it can mount a USB partition.

This was the original script:

#!/bin/nash


mount -t proc /proc /proc
setquiet
echo Mounted /proc filesystem
echo Mounting sysfs
mount -t sysfs none /sys
echo "Loading jbd.ko module"
insmod /lib/jbd.ko 
echo "Loading ext3.ko module"
insmod /lib/ext3.ko 
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
umount /sys
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc
Edit your script to load the USB drivers.
#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounted /proc filesystem
echo Mounting sysfs
mount -t sysfs none /sys
echo "Loading jbd.ko module"
insmod /lib/jbd.ko 
echo "Loading ext3.ko module"
insmod /lib/ext3.ko 
echo "*** Loading scsi_mod ***"
insmod /lib/scsi_mod.ko
echo "*** Loading sd_mod ***"
insmod /lib/sd_mod.ko
echo "*** Loading usb-storage ***"
insmod /lib/usb-storage.ko
echo "*** Loading usb-uhci ***"
insmod /lib/ehci-hcd.ko
echo "*** Sleeping 5 seconds ***"
/bin/sleep 5
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
echo "*** Reread partition table ***"
/sbin/sfdisk -R /dev/sda
umount /sys
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc

Copy kernel modules into the initrd image. For example, if you are running kernel 2.6.5-1.358 (uname -r to find out),

cd /lib/modules/2.6.5-1.358/kernel/drivers

cp  usb/ehci-hcd.ko /tmp/a/lib
cp  usb/storage/usb-storage.ko /tmp/a/lib
cp  scsi/scsi_mod.ko /tmp/a/lib
cp  scsi/sd_mod.ko /tmp/a/lib

Find out what libraries sleep and sfdisk use from the output of ldd:

ldd /bin/sleep
ldd /sbin/sfdisk

Copy the libraries into /tmp/a/lib. In my case it was:

mkdir /tmp/a/lib/tls
cp /lib/tls/libm.so.6 /tmp/a/lib/tls
cp /lib/tls/libpthread.so.0 /tmp/a/lib/tls
cp /lib/tls/libc.so.6 /tmp/a/lib/tls
cp /lib/tls/librt.so.1 /tmp/a/lib/tls
cp /lib/ld-linux.so.2 /tmp/a/lib

Copy the executables over:

cp /bin/sleep /tmp/a/bin
cp /sbin/sfdisk /tmp/a/sbin

Everything you need is now in the image, so unmount the image.

umount /tmp/a

ZIP it back up.

gzip /tmp/initrd

Copy it back into the boot partition.

cp /tmp/initrd.gz /boot/usbinird.img

Update your /boot/grub/grub.conf to use the new usbinitrd.img.  Here is what my grub.conf 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/sda2
# initrd /initrd-version.img
#boot=/dev/sda
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Fedora Core (2.6.5-1.358) USB 2.0 Boot
root (hd0,0)
kernel /vmlinuz-2.6.5-1.358 ro root=LABEL=/ rhgb quiet
#The following line is the custom made USB 2.0 boot image.
initrd /usbinird.img
#The following line was the original boot image.
#initrd /initrd-2.6.5-1.358.img

Your machine should now boot from the external USB 2.0 HDD!

Last updated May 30, 2004.