Friday, December 01, 2006

Installing DSL-N on a USB flash drive

Back in the eighties, our department was a VAX/VMS shop. We had a departmental VAX 11/780 in a server room downstairs, and serial lines ran through the building to terminals in computer labs and on desktops. In the late eighties, we started to see a few Unix machines. First, a Sun workstation, and then a bunch of DECstation 3100s, running Ultrix. I had the first of the latter on my desk. It had two external 500-megabyte SCSI disks in shoebox-sized enclosures. Each of these disks cost several thousand dollars.

Like everybody else, I've watched with amazement as the price per gigabyte of storage has dropped since then. I don't have any compelling reason to buy a thumb drive, but I decided I'd buy one when a gigabyte of storage got below $25. So, I recently ordered a cute little OCZ Roadster 1GB flash drive ($14 after the rebate) and I've been playing with it.

The things I wanted to have on the drive were:
  • A bootable Linux operating system
  • Some useful Windows utilities, like putty
  • Installation kits for things like Firefox
  • Reference documents
  • Plenty of space for whatever files I want to transport around by sneakernet
Ideally, I'd also like to have an encrypted zip archive for holding confidential files, and standalone browsers for this archive that work under Windows and Linux (at least).

Since the drive is only (!) 1GB, I didn't want to put KNOPPIX on it, although I use KNOPPIX from CD constantly. Since KNOPPIX takes up 700MB, that would only leave 300MB for other stuff, and I was worried that that might be too little sometimes. Another bootable CD distribution I'm familiar with is the much smaller (~50MB) Damn Small Linux (DSL). DSL is derived from KNOPPIX, and shares KNOPPIX's excellent hardware detection abilities. Unfortunately, though, DSL is based on a Linux 2.4 kernel, and I really wanted to use something based on 2.6, for better support for newer hardware. Because of this, I decided to go with DSL-N, which is a derivative of DSL that uses a 2.6 kernel and has some additional software.

Both the DSL and DSL-N bootable CDs include a graphical tool for installing the operating system onto a USB flash drive. So, I created a DSL-N 1.0-RC4 CD, booted it and gave it a try. DSL-N offers two ways of creating a bootable USB flash drive: USB zip or USB hdd. USB hdd is preferable, since it allows you to format the flash drive as a single large vfat partition. I tried this first, but found that my test machine wouldn't boot the drive, although it did detect it and list in as one of the bootable devices. So, I tried the USB zip configuration. In this configuration, the drive is divided into two partitions: a smaller boot partition at the front, and a larger partition on the rest of the drive for storing data. This configuration booted fine in the test machine.

But there's a problem with having more than one partition on the flash drive. I want to be able to use the drive under either Windows or Linux, but Windows only seems to be able to see the first partition on a flash device. Using the USB zip configuration, this would mean that the drive would be relatively useless on Windows computers.

So, I started looking at other options. Searching around the web, I saw some comments that made me suspect that the problem with booting the USB hdd configuration might be due to DSL-N's use of syslinux for booting. Since I'm more familiar with grub anyway, I thought I'd try to create a single-partition, grub-bootable configuration. Fortunately, other people have already done similar things. In particular, I found Jeremy Turner's "Grub Tips and Tricks" article from Free Software Magazine Issue 10, January/February 2006, extremely helpful. In it, he describes in detail how to install grub and DSL (but not DSL-N) on a USB flash drive.

First, I used fdisk to create a single partition on the flash drive, of type "W95 FAT32". Then I formatted the partition as a vfat filesystem:
/sbin/mkfs.vfat /dev/sdb1
(obviously adjust the device name to match whatever's appropriate for the system on which you're doing this.)

Then, following Jeremy Turner's DSL example, I created a "boot" directory tree on the flash drive, then mounted the DSL-N iso image and copied several files from it onto the flash drive:
mount /dev/sdb1 /mnt/flash
cd /mnt/flash
mkdir boot
mkdir boot/kernels
mkdir boot/images
mkdir boot/grub
mount -o loop /usr/src/dsl-n-01RC4.iso /mnt/iso
cp /mnt/iso/KNOPPIX/KNOPPIX /mnt/flash/images/dsl
cp /mnt/iso/isolinux/linux /mnt/flash/kernels/dsl-linux26
cp /mnt/iso/isolinux/minirt.gz /mnt/flash/images/dsl-minirt26.gz
umount /mnt/iso
sync
To make the drive bootable, the only other thing we need to do is install grub and configure it. Again, following Jeremy Turner's example I ran grub and used grub's filename completion feature as a way of determining which grub device corresponded to my flash drive:
grub> find /boot/grub/stage1
(hd0,1)
(hd1,1)
grub> find (hd1,0)/boot/im
grub> find (hd1,0)/boot/images/
Showing that (hd1,0) really is my flash drive, as I'd guessed, since there's no "images" directory under the boot directory on my hard disk. That being settled, I needed to copy grub's stage1, stage2, etc., files onto the flash drive, and create a grub configuration file.

To get the stage files copied over without missing anything, I just did a wholesale copy of my hard disks's grub directory:
cp -r -a -p /boot/grub/* /mnt/flash/boot/grub/
Since the flash drive partition is formatted vfat, I got a complaint at this point about the symbolic link "menu.lst -> ./grub.conf" in the original grub directory. The grub I'm using is configured to look for a configuration file called "grub.conf", so I called the file that in the flash drive's /boot/grub directory. I then edited grub.conf to make it initially look something like this:
default=0
timeout=10
root=(hd0,0)
title DSL-N 1.0RC4
kernel /boot/kernels/dsl-linux26 ramdisk_size=100000 init=/etc/init lang=us apm=power-off vga=791 toram nomce noapic quiet knoppix_dir=boot/images knoppix_name=dsl initrd=/boot/images/dsl-minirt26.gz BOOT_IMAGE=/boot/images/dsl
initrd /boot/images/dsl-minirt26.gz
I've broken the long kernel line here, but it's actually one long line. I'm not sure if some of the kernel parameters (like BOOT_IMAGE= and initrd=) are actually used, but they don't seem to hurt.

Then I told grub to install the boot loader:
grub> root (hd1,0)
grub> setup (hd1)
grub> quit
Next, try booting it in the test machine, and voila! it works. Experimenting with it, I do notice something that might be a peculiarity of the test machine: If I boot the machine cold (after the power has been turned off), the USB drive boots properly. If, instead, I reboot the machine without cycling the power, the results are unexpected. In some cases, the USB drive is ignored, and in others the DSL-N boot begins, but minirt fails to find the KNOPPIX image on the drive. These seem like timing issues. With that caveat, I'm pleased with the device so far.

(Update: Based on William Waddington's advice, I've also set the partition active, using fdisk, and installed grub on the active partition's boot sector. With these changes, I can now boot the drive on at least one machine that wouldn't boot it before.)

Since I'm using grub now, it's easy to add other bootable images. Here's what my current grub.conf file looks like:
default=0
timeout=10
root=(hd0,0)
title DSL-N 1.0RC4
kernel /boot/kernels/dsl-linux26 ramdisk_size=100000 init=/etc/init lang=us apm=power-off vga=791 toram nomce noapic quiet knoppix_dir=boot/images knoppix_name=dsl initrd=/boot/images/dsl-minirt26.gz BOOT_IMAGE=/boot/images/dsl
initrd /boot/images/dsl-minirt26.gz
title memtest86+-1.65
kernel /boot/kernels/memtest86+-1.65.bin
title NT/XP Password and Registry Editor
kernel /boot/kernels/memdisk
initrd /boot/images/bd050303.bin
title Super Grub Disk
kernel /boot/kernels/memdisk
initrd /boot/images/sgd_0.9528_english_floppy.img
As you can see, I've added memtest86+, the Offline NT Password and Registry Editor and Super Grub Disk.

In the rest of the disk, I store standalone Windows executables for putty, pscp, psftp and gzip,
and installers for Firefox, Wireshark and 7-Zip. And I have enough room left over for the 1916 edition of Webster's Unabridged dictionary, Shakespeare's First Folio and the King James Bible! Total disk usage so far is about 200MB. Still plenty of sneakernet bandwidth left.

No comments: