Hi,

I just figured out how to use a small USB pen drive as the primary
hard drive for Linux. This information floats on the net in bits and
pieces, so I figured I'd put it together. An update version can be
found here:

http://www.simonf.com/usb

1. Make sure your motherboard supports booting off of USB. You might
need to enable USB in the BIOS. Try all USB slots (one out of two did
not work for me).

2. You'll need to create a custom initrd image. Take your current
image from /boot (see /etc/lilo.conf or /etc/grub.conf for the exact
name). I'll call it initrd.img. (Use mkinitrd to create an initrd
image if you don't have one.)

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

3. gunzip /tmp/initrd.gz

4. mkdir /tmp/a

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

If this step fails, there is no loopback device support in your
kernel. You have to compile it in.

6. 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. Replace /tmp/a/linuxrc with this:

***

#!/bin/nash

echo "Loading jbd.o module"
insmod /lib/jbd.o
echo "Loading ext3.o module"
insmod /lib/ext3.o
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo "Loading usb modules"
insmod /lib/usbcore.o
insmod /lib/scsi_mod.o
insmod /lib/sd_mod.o
insmod /lib/usb-storage.o
insmod /lib/usb-uhci.o
/bin/sleep 5
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
/bin/sfdisk -R /dev/sda
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

***

The lines before "Loading usb modules" and after "echo 0x0100", as
well as mkdevices an mkrootdev are probably already there, so you just
need to insert the extra stuff. First the script loads all the
necessary kernel modules, then waits five seconds in order for the USB
code to recognize the disk, then runs sfdisk to reread the partition
table.

7. Copy kernel modules into the initrd image. For example, if you are
running kernel 2.4.22 ("uname -r" to find out),
cd /lib/modules/2.4.22/kernel/drivers
cp usb/usbcore.o /tmp/a/lib
cp usb/usb-uhci.o /tmp/a/lib
cp usb/storage/usb-storage.o /tmp/a/lib
cp scsi/scsi_mod.o /tmp/a/lib
cp scsi/sd_mod.o /tmp/a/lib

8. 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/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/librt.so.1 /tmp/a/lib
cp /lib/ld-linux.so.2 /tmp/a/lib

9. Copy the executables over:

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

10. umount /tmp/a

11. gzip /tmp/initrd

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

13. Update your lilo.conf or grub.conf to use the new usbinitrd.gz
with the same kernel that you grabbed the modules from. Run "lilo" or
"grub-install"

Simon Ilyushchenko

P.S. Presumably you can also patch the kernel to add a delay before a
USB device is mounted at boot time, but apparently not such patches
exist for the latest 2.4 kernel.