Scarlet Line home page Scarlet Line - SOFTWARE DESIGN & DEVELOPMENT

[Home]->[Documentation]->[How To ...]->[Create a Boot USB Memory Fob / Stick]

Expand All
Collapse All

How To Create a Boot USB Memory Fob / Stick


If you follow these instructions, you can create a cheap USB boot fob which can be used to boot any PC for tasks such as kickstart installation from e.g. NFS or HTTP, also DOS based BIOS upgrades. This does NOT require pxe or any special network card boot options. This will work both for directly connected monitor/keyboard and for serial console.

The USB Memory Stick

Find a USB memory stick ( also called Flash Drive ) of any capacity from a minimum of 16 MB to a maximum of 2 GB.

The smaller ones are often given away to advertise products. We only use a few megabytes of space, but extra space can be useful for example to hold multiple BIOS images, DOS tools, etc.

The stick can be no larger than 2 GB because many of the older BIOS are picky about disk format, so we are very conservative and use standard FAT16 for maximum compatability, which cannot support more than 2 GB.

It does NOT need to be a special "boot" flash disk, pretty much any fob will work using the following procedure. I use a Kingston Memory 1 GB DataTraveler USB Flash Drive simply because it was the cheapest 1 GB stick at Fry's.

fdisk the stick

To make the stick as generally accessible as possible, you need to fdisk it on a Linux machine. I suggest that you use a recent version of Linux ( i.e. kernel v2.6 ), the following example uses a recent Debian varient:

root@machine:# df
Filesystem ... Mounted on
/dev/sdg1      /media/SCARLETLINE

That now tells us that the first partition on the stick is /dev/sdg1 therefore the stick itself is /dev/sdg - yours may be elsewhere, e.g. /dev/sda

Now we know where it is, fdisk it:

root@machine:# fdisk /dev/sdg

Command (m for help): p

Disk /dev/sdg: 1026 MB, 1026555392 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdg1   *           1         125     1002464    6  FAT16
Partition 1 has different physical/logical endings:
     phys=(123, 254, 63) logical=(124, 205, 16)

When you run fdisk, use the p command to see how it is currently partitioned. The goal is to have one partition of type Id 6 which fills the whole stick, as above.

Use the d command to delete all existing partitions.

Use the n-p-1 command to create a primary first partition using all available sectors.

Next, use a to toggle it bootable.

Use the t-6 command to set the type to FAT16.

Finally use the w command to write the partition table, and exit.

Here is a sample session performing all of the above actions:

Command (m for help): d
Selected partition 1

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
Partition number (1-4): 1
First cylinder (1-124, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-124, default 124):
Using default value 124

Command (m for help): p

Disk /dev/sdg: 1026 MB, 1026555392 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdg1               1         124      995998+  83  Linux

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/sdg: 1026 MB, 1026555392 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdg1   *           1         124      995998+  83  Linux

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 6
Changed system type of partition 1 to 6 (FAT16)

Command (m for help): p

Disk /dev/sdg: 1026 MB, 1026555392 bytes
255 heads, 63 sectors/track, 124 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdg1   *           1         124      995998+   6  FAT16

Install FreeDOS

Download a FreeDOS boot CD image from Download FreeDOS

You can use fdbootcd.iso or fdfullcd.iso if you prefer.

Create a boot CD using an iso burning tool that understands boot images, such as WinISO.

Boot your computer from the FreeDOS CD with your Memory stick inserted in a free USB socket. If you use a new enough PC, then the USB stick will appear as a drive letter to FreeDOS. In this example it is drive C: , be very careful not to do this to the wrong drive:


The /S option copies the dos boot files to the correct sectors ( KERNEL.SYS and COMMAND.COM ), the /V option sets the volume label. Set the volume label to anything you like up to eleven characters. I suggest all upper case no spaces or punctuation for maximum usability.

You now have a formatted and bootable stick. Copy the FreeDOS files to the stick. You will need the two directories called DRIVER and FREEDOS and the file FDCONFIG.SYS from your boot drive. You can use XCOPY to do this.

Once you have copied all of those files, you should have something like the following contents on the stick:

Folder PATH listing for volume SCARLETLINE
Volume serial number is 0000569F 6026:8AE7
|       ADD.COM
|       CHOICE.EXE
|       FDISK.EXE
|       FDISK.INI
|       FORMAT.EXE
|       INIADD.COM
|       LOCATE.COM
|       META-ALL.BIN
|       TUNZ.COM
|       FDAUTO.BAT
|       SYS.COM
|       FDBOOT.BAT

We have now finished with the FreeDOS session, you can eject the CDROM and reboot to your usual operating system.

Using your favorite editor you will need to edit FDCONFIG.SYS and FREEDOS/FDAUTO.BAT

Basically, you just need to change any references to the A: drive to the C: drive, as you are switching from what FreeDOS considers a floppy boot, to a hard disk boot.

The FDAUTO.BAT can be totally wiped. Here are mine:


; FreeDOS Beta 9 distro  by Jeremy Davis [], 
; last update 2005-11-30 by Bernd Blaauw []
; config.sys loads system drivers. Please edit to suit your needs.
MENU [1] Load XMSdriver   [2] SafeMode   [3] Ask me (default)  [4] HIMEM+EMM386

No, I have no idea where the SPECIAL directory is.


@echo off

Install grub

You can usually find these files on a Linux computer in the directory /lib/grub/ under a machine name subdirectory, such as i386-pc. Rememeber that you want them as widely bootable as possible, so choose i386 over i686 or x86_64. I got them from a Knoppix Live CD as they are chosen to work on any pc.

touch /boot/grub/fob_flag

Now start grub, I suggest you use a recent Linux distro, mine has grub v0.97. Here is why we created that flag, so that we could find it:

# grub
grub> find /boot/grub/fob_flag
find /boot/grub/fob_flag

On my machine it was found at (hd2,0) yours may be different. Use your found location to set the root, and setup grub on the stick. Replace (hd2,0) with your location below:

grub> root (hd2,0)
root (hd2,0)
 Filesystem type is fat, partition type 0x6
grub> setup (hd2)
grub> quit


Finally you need a /boot/grub/menu.lst file. Here is mine:

# Boot over either monitor/keyboard or serial
serial --unit=0 --speed=19200 --word=8 ==parity=no --stop=1
terminal --timeout=10 serial console


title Kickstart Install - monitor keyboard via internal nfs
        root (hd0,0)
        kernel /kicks/vmlinuz lang=en ks=nfs: ksdevice=eth0
        initrd /kicks/initrd.gz
title Kickstart Install - serial console via internal nfs
        root (hd0,0)
        kernel /kicks/vmlinuz console=ttyS0,19200n8 lang=en ks=nfs: ksdevice=eth0
        initrd /kicks/initrd.gz
title Kickstart Install - monitor keyboard via http
        root (hd0,0)
        kernel /kicks/vmlinuz lang=en ks= ksdevice=eth0
        initrd /kicks/initrd.gz
title Kickstart Install - serial console via http
        root (hd0,0)
        kernel /kicks/vmlinuz console=ttyS0,19200n8 lang=en ks= ksdevice=eth0
        initrd /kicks/initrd.gz
title FreeDOS
	root (hd0,0)
        chainloader +1
title MemTest
        root (hd0,0)
        kernel /boot/isolinux/memtest

The MemTest utility is a useful tool for testing a new PC, and it came from the Knoppix Live CD. The kickstart images are described below.

Here are the files that we added to get grub to work:

        |   stage1
        |   stage2
        |   fat_stage1_5
        |   fob_flag
        |   menu.lst

Add Linux kernels and initrd images

In order to boot Linux from the USB fob, at a minimum you need two files, a Linux kernel ( usually named vmlinuz ) and an initrd image, which is a compressed image of the boot file system, including drivers and init process.

        vmlinuz      898,209 bytes
        initrd.gz  2,633,145 bytes

These files can be obtained from your Linux distro, and modified if necessary as below.

See the grub menu.lst above to see how to boot from these.

The initrd image boots up, and then runs /linuxrc which in the above case runs anaconda to install Linux, and all our kickstart additions, on the hardware.

Edit initrd image

Usually you will not need to edit the initrd image, but if you do, here is how. I have written two shell scripts to open out, and to pack up, initrd images. They are not very long, listed below. The reason for the shell scripts is that several mechanisms are used in creating and editting these images.


If your image is called initrd.gz, then the usage is:

./unfurl initrd

This will create a directory called initrd which contains all the files and modules, and can be edited.

mkdir /tmp/unfurl
gunzip -c $1.gz > /tmp/unfurl/initrd.img
mkdir /tmp/unfurl/initrd_img
mount -o loop /tmp/unfurl/initrd.img /tmp/unfurl/initrd_img
rm -rf $1
mkdir $1
mkdir $1/initrd_img
mkdir $1/modules
cp -a /tmp/unfurl/initrd_img/* $1/initrd_img/
umount /tmp/unfurl/initrd_img
rm -rf /tmp/unfurl
cd $1/modules
zcat ../initrd_img/modules/modules.cgz | cpio -id
cd ..
chmod -R 777 *


If you have a directory called initrd, organized as unfurl does, above, then usage:

./furl initrd

will create a new initrd image called initrd.gz containing the files from the initrd directory.

cd $1/modules
find * | cpio -ov -H crc | gzip -c9 > ../initrd_img/modules/modules.cgz
cd ../..
INITRD_SIZE=`du -k -s $1/initrd_img | awk '{print $1}'`
mkdir /tmp/furl
mkdir /tmp/furl/initrd_img
dd if=/dev/zero bs=1k count=$NEW_INITRD_SIZE of=/tmp/furl/initrd.img
echo "y" | /sbin/mke2fs /tmp/furl/initrd.img > /dev/null
mount -o loop /tmp/furl/initrd.img /tmp/furl/initrd_img
cp -a $1/initrd_img/* /tmp/furl/initrd_img/
umount /tmp/furl/initrd_img
rm -rf $1.gz
gzip -c /tmp/furl/initrd.img > $1.gz
rm -rf /tmp/furl
chmod -R 777 $1.gz

Boot from USB

You can boot from monitor/keyboard or serial console, as you wish - though often you will need monitor/keyboard at first to set the BIOS.

Setting up BIOS settings to boot from USB Memory stick can be complex on older BIOSes. On newer machines it is very easy. You are looking to enable USB-HDD or something like that. Here are some notes on specific BIOSes:

Award BIOS setup

If you have an older Award BIOS, the procedure to get it to boot from USB fob is a bit odd due to problems which are fixed in more recent BIOSes. Here is an example on one PC:

Note that this message appears under the pci device listing on the monitor - it does not appear on the serial console but you will know because the machine stops after the pci device list

If you had already inserted the fob, THEN REMOVE AND RE-INSERT IT now or it will not work.

    GNU GRUB  version 0.95  (640K lower / 244672K upper memory)

 | Kickstart Install - monitor keyboard                                    |
 | Kickstart Install - serial console                                      |
 | FreeDOS                                                                 |
 | MemTest                                                                 |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
 |                                                                         |
      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS, 'e' to edit the
      commands before booting, or 'c' for a command-line.

Kickstart considerations

In order to kickstart a custom Linux installation, you need dhcpd running on your LAN, you need to configure the kernel boot options in the GRUB menu to automatically find the kickstart files over your network, and of course you need to provide those files using a network protocol such as NFS or HTTP.


Unfortunately some Linux distros are unable to use standard dhcp as provided by e.g. cheap routers from Linksys, instead they require a Linux computer running dhcpd. I am using a recent Debian varient with the following /etc/dhcp3/dhcpd.conf file:

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
option domain-name "";
option domain-name-servers,;

option subnet-mask;
option broadcast-address;
option routers;

subnet netmask {

default-lease-time 7200;
max-lease-time 86400;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.

Linux kernel boot options

If you look at the menu.lst file above, in the GRUB section, you will see two kickstart parameters:

  1. ksdevice=
  2. ks=

The first is needed if your hardware has more than one ethernet port, to tell anaconda which one you have plugged your network cable into, I suggest eth0

The second tells anaconda where your kickstart configuration file is, e.g. nfs: which is the default if installing internally, or http :// which uses a standard Apache web server running on