You must be the root user for many of these operations and that means you can really mess up your system if you are careless or hasty.
If possible, you should already have made a boot disk set based on rote instructions that came with your Linux distribution.
You cannot depend on instructions that are appropriate for my system also being appropriate for your system. (My system has a Matrox Millennium video card with 8 MB VRAM and an Adaptec 2940UW SCSI Adapter.)
The Bootdisk-HOWTO gives more general instructions.
What is contained in this page is only a subset of those instructions.
Craig Van Degrift / craig@yosemitefoothills.com / content last revised February 27, 2000This is the really useful boot disk choice. It loads a minimal Linux system entirely in RAM so that you can examine, tinker with, or fix your hard disk partitions from an independent Linux system.
The following instructions have been updated to use libc.so.6 (glibc) and to skip password checking. The boot diskette is unchanged, but the root and usr diskettes are quite different. Contact me if you need the old instructions. I didn't have enough free room on my WWW site for both versions.
Put a blank diskette in /dev/fd0 and put an ext2 filesystem on it by doing:
mke2fs -m 0 /dev/fd0
The "-m 0" option specifies that no reserved space shall be set aside solely for use by the root user. Doing so would add an unnecessary complication since the entire root diskette is expected to be used by the root user.
Note: The previous sentence highlights a point of confusion with Unix terminology. The "root filesystem" has no special connection with the "root user"! Also, the directory "/" is the "root directory", and the directory "/root" is the home directory of the "root user".
Next, mount this diskette, cd to it, and remove the lost+found directory - we don't need it:
mount /mnt/floppy cd /mnt/floppy rmdir lost+found
Now make a miniature /dev directory for the kernel to use until it gets the root filesystem mounted:
mkdir dev cd dev
and populated it with /dev/null and storage devices that might contain the boot disk, a kernel image, or the root filesystem. The following command sequences do this for my system which only has SCSI fixed disks:
mknod null c 1 3; chmod 666 null ; chown root:root null mknod fd0 b 2 0; chmod 660 fd0 ; chown root:floppy fd0 mknod fd1 b 2 2; chmod 660 fd0 ; chown root:floppy fd0 mknod sda b 8 0; chmod 660 sda ; chown root:disk sda mknod sda1 b 8 1; chmod 660 sda1 ; chown root:disk sda1 mknod sda2 b 8 2; chmod 660 sda2 ; chown root:disk sda2 mknod sda3 b 8 3; chmod 660 sda3 ; chown root:disk sda3 mknod sda4 b 8 4; chmod 660 sda4 ; chown root:disk sda4 mknod sda5 b 8 5; chmod 660 sda5 ; chown root:disk sda5 mknod sda6 b 8 6; chmod 660 sda6 ; chown root:disk sda6 mknod sda7 b 8 7; chmod 660 sda7 ; chown root:disk sda7 mknod sda8 b 8 8; chmod 660 sda8 ; chown root:disk sda8 mknod sdb b 8 16; chmod 660 sdb ; chown root:disk sdb mknod sdb1 b 8 17; chmod 660 sdb1 ; chown root:disk sdb1 mknod sdb2 b 8 18; chmod 660 sdb2 ; chown root:disk sdb2 mknod sdb3 b 8 19; chmod 660 sdb3 ; chown root:disk sdb3 mknod sdb4 b 8 20; chmod 660 sdb4 ; chown root:disk sdb4 mknod sdb5 b 8 21; chmod 660 sdb5 ; chown root:disk sdb5 mknod sdb6 b 8 22; chmod 660 sdb6 ; chown root:disk sdb6 mknod sdb7 b 8 23; chmod 660 sdb7 ; chown root:disk sdb7 mknod sdb8 b 8 24; chmod 660 sdb8 ; chown root:disk sdb8
For an IDE/EIDE system, I think the commands would be:
mknod null c 1 3; chmod 555 null ; chown root:root null mknod fd0 b 2 0; chmod 666 fd0 ; chown root:disk fd0 mknod fd1 b 2 1; chmod 666 fd1 ; chown root:disk fd1 mknod hda b 3 0; chmod 660 hda ; chown root:disk hda mknod hda1 b 3 1; chmod 660 hda1 ; chown root:disk hda1 mknod hda2 b 3 2; chmod 660 hda2 ; chown root:disk hda2 mknod hda3 b 3 3; chmod 660 hda3 ; chown root:disk hda3 mknod hda4 b 3 4; chmod 660 hda4 ; chown root:disk hda4 mknod hda5 b 3 5; chmod 660 hda5 ; chown root:disk hda5 mknod hda6 b 3 6; chmod 660 hda6 ; chown root:disk hda6 mknod hdb b 3 64; chmod 660 hdb ; chown root:disk hdb mknod hdb1 b 3 65; chmod 660 hdb1 ; chown root:disk hdb1 mknod hdb2 b 3 66; chmod 660 hdb2 ; chown root:disk hdb2 mknod hdb3 b 3 67; chmod 660 hdb3 ; chown root:disk hdb3 mknod hdb4 b 3 68; chmod 660 hdb4 ; chown root:disk hdb4 mknod hdb5 b 3 69; chmod 660 hdb5 ; chown root:disk hdb5 mknod hdb6 b 3 70; chmod 660 hdb6 ; chown root:disk hdb6
Next, create a directory /boot and put lilo's boot sectors, boot.b and chain.b in it:
cd .. mkdir boot cd boot cp -a /boot/boot.b . cp -a /boot/chain.b . cd ..
Put the kernel image into the top directory of the boot floppy:
cp /boot/bzImage .
(or whatever is the appropriate path and name for your normal Linux kernel image)
At this point you could use rdev to adjust the kernel's boot parameters, but we are going to boot Lilo and it is better to let Lilo do such things.
We must now create a configuration file for lilo on the diskette. Mine is called "bdlilo.conf" and I place it in the top directory of the boot diskette. It contains:
boot = /dev/fd0 install = /mnt/floppy/boot/boot.b map = /mnt/floppy/boot/map backup = /dev/null compact prompt default = Linux_on_fd0 image = /mnt/floppy/bzImage label = Linux_on_fd0 root = /dev/fd0 vga = 0x012c append = "ramdisk_size=8192 load_ramdisk=1 prompt_ramdisk=1 ramdisk_start=0" image = /boot/linux-2.2.12/bzImage label = Linux_on_sdb5 root = /dev/sdb5 other = /dev/sda label = Boot_Manager loader = /mnt/floppy/boot/chain.b
At this point, everything is in place and we can finish up by doing:
/sbin/lilo -v -C /mnt/floppy/bdlilo.conf cd .. umount /mnt/floppy
To understand the Lilo configuration file, we must understand what Lilo accomplishes:
This is where the BIOS, BootManager, or other booting programs will look for a boot sector. The original boot sector, as a precaution, is saved as a file (specified by backup=...).
One reason that Lilo's configuration file is confusing is that some of the parameters apply to the time you run /sbin/lilo and other parameters apply to the time when the system is booted. For example, install, map, and image tell /sbin/lilo where to find or place things and therefore apply to the time when you run /sbin/lilo, but the root parameter and the contents of "append="..." are placed into the kernel and used by it only at the time when it is booting.
Therefore, if you plan to boot the diskette using device /dev/fd0, you will specify root=/dev/fd0 even if it is currently being assembled while mounted in /dev/fd1. Similar considerations apply when preparing a removable hard disk or preparing a second hard drive for the possible time when it may be mounted as the first drive (e.g. in the event of the failure of your first drive).
Another reason for confusion is that the terms boot and install are not clearly defined. install specifies where /sbin/lilo is to find boot.b when preparing the diskette, and boot specifies which device is to have its first sector filled with the first 446 bytes of the boot.b file, 64 bytes of the disk partition table, and the two boot sector magic bytes 0x55 and 0xaa.
"backup=..." specifies where Lilo should save the boot sector that is being replaced by boot.b. This is important when messing with the master boot record that has important partitioning information in it.
The labels are simply convenience names to distinguish between the different boot images. They are displayed during boot if the user doesn't use the default image (specified by default=...); they are of no significance to the kernel.
Some directives such as compact and default= are options for /sbin/lilo itself. prompt tells Lilo you would like to interact with Lilo at boot time.
Lilo's biggest job is to make a mapping of where the specified images are located on the storage medium. Ordinarily, as we use a filesystem, its directories make irrelevant exactly where the data is physically placed on a storage device. During the boot process, however, nothing is known about filesystems and their directories. The only way files can be accessed during the boot is by physical addresses like drive, head, track, and sector numbers.
Lilo must therefore make a cross-reference file that tells the boot routines these hardware addresses. The map=... specification tells Lilo where you want this map file is to be placed in the filesystem during the execution of /sbin/lilo. The sectors of this map will be communicated to the boot routines for use during boot; its filename is for our convenience only; it is of no use to the kernel during boot. This map should be placed on the diskette so that the "boot" diskette is completely independent of the hard disk.
The completed boot diskette for my SCSI system has a ls -AlR that is:
.: total 537 -rw-r--r-- 1 root root 452 Feb 10 14:25 bdlilo.conf drwxr-xr-x 2 root root 1024 Feb 10 14:27 boot drwxr-xr-x 2 root root 1024 Feb 10 14:03 dev -rw-r--r-- 1 root root 542597 Feb 10 14:07 vmlinuz-2.2.14 ./boot: total 15 -rw-r--r-- 1 root root 4540 Jan 27 05:49 boot.b -rw-r--r-- 1 root root 612 Jan 27 05:49 chain.b -rw------- 1 root root 8704 Feb 10 14:27 map ./dev: total 0 brw-rw---- 1 root 25 2, 0 Feb 10 13:55 fd0 brw-rw---- 1 root 25 2, 1 Feb 10 13:55 fd1 crw-rw-rw- 1 root root 1, 3 Feb 10 13:53 null brw-rw---- 1 root disk 8, 0 Feb 10 13:56 sda brw-rw---- 1 root disk 8, 1 Feb 10 13:57 sda1 brw-rw---- 1 root disk 8, 2 Feb 10 13:58 sda2 brw-rw---- 1 root disk 8, 3 Feb 10 13:58 sda3 brw-rw---- 1 root disk 8, 4 Feb 10 14:00 sda4 brw-rw---- 1 root disk 8, 5 Feb 10 14:01 sda5 brw-rw---- 1 root disk 8, 6 Feb 10 14:01 sda6 brw-rw---- 1 root disk 8, 7 Feb 10 14:01 sda7 brw-rw---- 1 root disk 8, 8 Feb 10 14:01 sda8 brw-rw---- 1 root disk 8, 16 Feb 10 13:57 sdb brw-rw---- 1 root disk 8, 17 Feb 10 14:02 sdb1 brw-rw---- 1 root disk 8, 18 Feb 10 14:02 sdb2 brw-rw---- 1 root disk 8, 19 Feb 10 14:02 sdb3 brw-rw---- 1 root disk 8, 20 Feb 10 14:02 sdb4 brw-rw---- 1 root disk 8, 21 Feb 10 14:02 sdb5 brw-rw---- 1 root disk 8, 22 Feb 10 14:03 sdb6 brw-rw---- 1 root disk 8, 23 Feb 10 14:03 sdb7 brw-rw---- 1 root disk 8, 24 Feb 10 14:03 sdb8
Only one diskette drive unit is needed for the entire boot. Once the boot diskette has been read and the kernel started, a prompt will be given to insert the "root" diskette. The "root" diskette goes into the same drive because of the line in bdlilo.conf that specified root = /dev/fd0. The compressed "root" file system is then decompressed into a ram disk the kernel has setup for it in RAM memory. The "root" diskette is then no longer needed and may be removed. A "/usr" diskette, if needed, may then be inserted into the same drive.
Making the root diskette from scratch is quite a bit of work, but once it and some accompanying scripts and directories have been arranged, further modification to it becomes a breeze. One suitable for my system is available here (1412142 bytes) under the abbreviated name rootfs_n.gz. It is the file rootfs_new.gz described in this section.
The root diskette is a compressed filesystem; 3.3 MB of files are compressed, together with a containing ext2 filesystem, into a package that fits into the 1440 1kb blocks available on a normal diskette. You cannot, however, simple make a directory with the files and compress that directory. Doing so would make a compressed file of the directory, but not of a complete filesystem with files.
The necessary magic can be done in several ways, but the neatest (as detailed below) is to mount a suitably created empty file as a "loop filesystem" (mount -o loop), cd into it, populate it with your files, umount it, and gzip it. This produces a compressed file that contains the encapsulating filesystem together with its files. This compressed file is then placed on a diskette with a dd if=... of=... bs=1k command.
There is still one subtle point. When you cd into the mounted loop filesystem and are setting things up, you will probably delete files on occasion. This removes their directory entries, but otherwise leaves troublesome non-zero bits that will not compress as well as blocks full of zeros when the system is compressed with gzip.
Thus, you must keep an old copy and freshly generate a new copy after each edit. Here are a couple of scripts and a directory layout that make this easy. In an empty working directory, say /boot/bootdisk, create two subdirectories mnt_old and mnt_new to serve as mount points for two loop devices, an old one and a new one:
mkdir /boot/bootdisk cd /boot/bootdisk mkdir mnt_old mnt_new
To give yourself a head start, you can preload this directory with my file by downloading rootfs_n.gz (1467 kB).
cp rootfs_n.gz /boot/bootdisk/rootfs_new.gz
Now, create the following script named start to start your editing session:
# start - a shell script to prepare for editing of root filesystem diskette. cd /boot/bootdisk mv rootfs_new.gz rootfs_old.gz gunzip rootfs_old.gz dd if=/dev/zero of=rootfs_new bs=1k count=8192 mke2fs -m 0 -F rootfs_new mount -o loop rootfs_new mnt_new mount -o loop rootfs_old mnt_old cd mnt_new; rmdir lost+found; mkdir proc; cd .. cd mnt_old; rmdir proc; cd .. df
And also a script named finish is useful to finish up when you are done editing:
# stop - a shell script to finish up after editing root diskette cd /boot/bootdisk/mnt_old cp -a . ../mnt_new cd .. df umount mnt_new mnt_old gzip -v9 rootfs_new gzip -v9 rootfs_old dd if=rootfs_new.gz of=/dev/fd0 bs=1k ls -Al
And be sure to do:
chmod +x start finish
so they can be run.
If you examine these scripts, you will see that they allow you to create a fresh "root" diskette after each edit session using the previous edit's result as a starting point.
The "dd if=/dev/zero of=rootfs_new bs=1k count=8192" line in start creates a zero-filled file 8192 kb in size. "mke2fs -m 0 -F rootfs_new" then puts an ext2 filesystem on that file. Since only the root user is likely to be using the file, there is no purpose in reserving some space just for root; the option -m 0 handles this. The -F options is used to avoid needing to tell mount that we really know what we are doing as we make the filesystem on a file rather than a device.
Next, the new and old files are mounted with the -o loop option (-t ext2 and -o rw are assumed). The new filesystem will have been created with an unnecessary lost+found directory placed in it which the start script removes.
The /proc directory is handled specially to avoid any chance that it will be unintentionally used by the kernel (This can happen if you do a chroot to any directory containing a subdirectory named proc.)
We are finally ready to cd mnt_old and do our editing.
When done editing, we then execute the finish script which unmounts the filesystems, gzips them up, and copies the new version to a diskette placed in /dev/fd0. The script does not check if the file has exceed the 1440 block limit, presuming that the operator is watching out for the size. (I expect that when it is too big, there will be a complaint from the dd instruction.
Now, what should be placed on the diskette? Here is a listing of what I have selected:
.: total 21 drwxr-xr-x 2 root root 1024 Feb 10 16:48 backup drwxr-xr-x 2 root root 1024 Feb 10 16:48 biglinux drwxr-xr-x 2 root root 1024 Feb 17 13:28 bin drwxr-xr-x 2 root root 1024 Feb 10 16:48 cdrom drwxr-xr-x 2 root root 2048 Feb 14 14:24 dev drwxr-xr-x 2 root root 1024 Feb 10 16:48 dos drwxr-xr-x 13 root root 1024 Feb 17 15:17 etc drwxr-xr-x 2 root root 1024 Feb 10 16:48 extra -rw-r--r-- 1 root root 0 Dec 7 11:13 fastboot drwxr-xr-x 2 root root 1024 Feb 10 16:48 floppy drwxr-xr-x 2 root root 1024 Feb 10 16:48 floppyB drwxr-xr-x 3 root root 1024 Feb 14 12:07 home drwxr-xr-x 4 root root 1024 Feb 17 14:55 lib drwxr-xr-x 2 root root 1024 Feb 10 16:48 os2 drwxr-xr-x 2 root root 1024 Feb 17 14:54 proc drwxr-xr-x 2 root root 1024 Feb 15 03:54 root drwxr-xr-x 2 root root 1024 Feb 17 13:30 sbin drwxr-xr-x 2 root root 1024 Feb 10 16:48 tinyos2 drwxr-xr-x 2 root root 1024 Feb 10 15:36 tmp drwxr-xr-x 2 root root 1024 Feb 11 08:14 usr drwxr-xr-x 6 root root 1024 Feb 11 07:44 var ./backup: total 0 ./biglinux: total 0 ./bin: total 1534 -rwxr-xr-x 1 root root 461720 Feb 10 16:00 bash -rwxr-xr-x 1 root root 9668 Feb 10 16:00 cat -rwxr-xr-x 1 root root 12108 Feb 14 13:05 chgrp -rwxr-xr-x 1 root root 12700 Feb 10 16:00 chmod -rwxr-xr-x 1 root root 11824 Feb 10 16:00 chown -rwxr-xr-x 1 root root 6220 Feb 10 16:00 chroot -rwxr-xr-x 1 root root 32176 Feb 10 16:00 cp -rwxr-xr-x 1 root root 25712 Feb 10 16:00 date -rwxr-xr-x 1 root root 25904 Feb 10 16:00 dd -rwxr-xr-x 1 root root 23696 Feb 10 16:00 df -rwxr-xr-x 1 root root 14192 Feb 14 19:13 dircolors -rwxr-xr-x 1 root root 4112 Feb 11 07:19 dmesg -rwxr-xr-x 1 root root 23920 Feb 10 16:00 du -rwxr-xr-x 1 root root 6300 Feb 10 16:00 env -rwxr-xr-x 1 root root 54900 Feb 14 12:12 find -r-xr-xr-x 1 root root 5300 Feb 10 16:00 free -rwxr-xr-x 1 root root 74848 Feb 14 12:39 grep lrwxrwxrwx 1 root root 4 Feb 17 15:32 gunzip -> gzip -rwxr-xr-x 1 root root 46160 Feb 10 16:00 gzip -rwxr-xr-x 1 root root 15768 Feb 10 16:00 hexdump -rwxr-xr-x 1 root root 10296 Feb 10 16:00 hostname -rwxr-xr-x 1 root root 9552 Feb 10 16:00 id -rwxr-xr-x 1 root root 10660 Feb 15 03:13 last -rwxr-xr-x 1 root root 78096 Feb 10 16:00 less -rwxr-xr-x 1 root root 18832 Feb 10 16:00 ln -rwxr-xr-x 1 root root 8488 Feb 14 12:16 locate -rwxr-xr-x 1 root root 40816 Feb 10 16:00 ls -rwxr-xr-x 1 root root 13088 Feb 10 16:00 mkdir -rwxr-xr-x 1 root root 19536 Feb 14 18:21 mke2fs -rwxr-xr-x 1 root root 11604 Feb 10 16:00 mknod -rwxr-xr-x 1 root root 65360 Feb 10 16:00 mount -rwxr-xr-x 1 root root 39952 Feb 10 16:00 mv -r-xr-xr-x 1 root root 58704 Feb 10 16:00 ps lrwxrwxrwx 1 root root 4 Feb 17 15:32 reset -> tset -rwxr-xr-x 1 root root 20304 Feb 10 16:00 rm -rwxr-xr-x 1 root root 6892 Feb 10 16:00 rmdir -rwxr-xr-x 1 root root 44048 Feb 14 18:53 sed -rwxr-xr-x 1 root root 20912 Feb 10 16:00 setterm lrwxrwxrwx 1 root root 4 Feb 17 15:32 sh -> bash -rwxr-xr-x 1 root root 5952 Feb 10 16:00 sleep -rwxr-xr-x 1 root root 27312 Feb 14 18:09 sort -rwxr-xr-x 1 root root 27180 Feb 10 16:00 stty -rwxr-xr-x 1 root root 22640 Feb 15 03:12 touch -rwxr-xr-x 1 root root 7324 Feb 10 16:00 tput -rwxr-xr-x 1 root root 29200 Feb 10 16:00 tset -rwxr-xr-x 1 root root 36528 Feb 10 16:00 umount -rwxr-xr-x 1 root root 6420 Feb 11 07:18 uname -rwxr-xr-x 1 root root 5794 Feb 14 12:16 updatedb ./cdrom: total 0 ./dev: total 0 lrwxrwxrwx 1 root root 4 Feb 17 15:32 cdrom -> scd0 crw-r--r-- 1 root root 5, 1 Feb 11 03:50 console brw-rw---- 1 root 25 2, 0 Feb 9 14:43 fd0 brw-rw---- 1 root 25 2, 1 Feb 9 14:43 fd1 brw-rw---- 1 root disk 3, 0 Feb 14 11:47 hda brw-rw---- 1 root disk 3, 1 Feb 14 11:47 hda1 brw-rw---- 1 root disk 3, 2 Feb 14 11:48 hda2 brw-rw---- 1 root disk 3, 3 Feb 14 11:48 hda3 brw-rw---- 1 root disk 3, 4 Feb 14 11:48 hda4 brw-rw---- 1 root disk 3, 5 Feb 14 11:48 hda5 brw-rw---- 1 root disk 3, 6 Feb 14 11:48 hda6 brw-rw---- 1 root disk 3, 7 Feb 14 11:48 hda7 brw-rw---- 1 root disk 3, 8 Feb 14 11:49 hda8 brw-rw---- 1 root disk 3, 64 Feb 14 11:49 hdb brw-rw---- 1 root disk 3, 65 Feb 14 11:49 hdb1 brw-rw---- 1 root disk 3, 66 Feb 14 11:50 hdb2 brw-rw---- 1 root disk 3, 67 Feb 14 11:50 hdb3 brw-rw---- 1 root disk 3, 68 Feb 14 11:50 hdb4 brw-rw---- 1 root disk 3, 69 Feb 14 11:50 hdb5 brw-rw---- 1 root disk 3, 70 Feb 14 11:51 hdb6 brw-rw---- 1 root disk 3, 71 Feb 14 11:51 hdb7 brw-rw---- 1 root disk 3, 72 Feb 14 11:51 hdb8 brw-rw---- 1 root disk 3, 128 Feb 14 11:52 hdc brw-rw---- 1 root disk 3, 129 Feb 14 11:52 hdc1 brw-rw---- 1 root disk 3, 130 Feb 14 11:52 hdc2 brw-rw---- 1 root disk 3, 131 Feb 14 11:52 hdc3 brw-rw---- 1 root disk 3, 132 Feb 14 11:52 hdc4 brw-rw---- 1 root disk 3, 192 Feb 14 11:53 hdd brw-rw---- 1 root disk 3, 193 Feb 14 11:53 hdd1 brw-rw---- 1 root disk 3, 194 Feb 14 11:53 hdd2 brw-rw---- 1 root disk 3, 195 Feb 14 11:54 hdd3 brw-rw---- 1 root disk 3, 196 Feb 14 11:54 hdd4 brw-rw---- 1 root disk 7, 0 Sep 8 18:53 loop0 brw-rw---- 1 root disk 7, 1 Sep 8 18:53 loop1 brw-rw---- 1 root disk 7, 2 Sep 8 18:53 loop2 brw-rw---- 1 root disk 7, 3 Sep 8 18:53 loop3 brw-rw---- 1 root disk 7, 4 Sep 8 18:53 loop4 brw-rw---- 1 root disk 7, 5 Sep 8 18:53 loop5 brw-rw---- 1 root disk 7, 6 Sep 8 18:53 loop6 brw-rw---- 1 root disk 7, 7 Sep 8 18:53 loop7 crw-rw-rw- 1 root root 1, 3 Sep 8 18:52 null brw-rw---- 1 root disk 1, 0 Sep 8 18:52 ram0 brw-rw---- 1 root disk 1, 1 Sep 8 18:52 ram1 brw-rw---- 1 root disk 1, 2 Sep 8 18:52 ram2 brw-rw---- 1 root disk 1, 3 Sep 8 18:52 ram3 brw-rw---- 1 root disk 1, 4 Sep 8 18:52 ram4 brw-rw---- 1 root disk 1, 5 Sep 8 18:52 ram5 brw-rw---- 1 root disk 1, 6 Sep 8 18:52 ram6 brw-rw---- 1 root disk 1, 7 Sep 8 18:52 ram7 brw-rw---- 1 root 24 11, 0 Feb 9 14:47 scd0 brw-rw---- 1 root 24 11, 1 Feb 9 14:47 scd1 brw-rw---- 1 root disk 8, 0 Sep 8 18:52 sda brw-rw---- 1 root disk 8, 1 Sep 8 18:52 sda1 brw-rw---- 1 root disk 8, 2 Sep 8 18:52 sda2 brw-rw---- 1 root disk 8, 3 Sep 8 18:52 sda3 brw-rw---- 1 root disk 8, 4 Sep 8 18:52 sda4 brw-rw---- 1 root disk 8, 5 Sep 8 18:52 sda5 brw-rw---- 1 root disk 8, 6 Sep 8 18:52 sda6 brw-rw---- 1 root disk 8, 7 Sep 8 18:52 sda7 brw-rw---- 1 root disk 8, 8 Sep 8 18:52 sda8 brw-rw---- 1 root disk 8, 16 Sep 8 18:52 sdb brw-rw---- 1 root disk 8, 17 Sep 8 18:52 sdb1 brw-rw---- 1 root disk 8, 18 Sep 8 18:52 sdb2 brw-rw---- 1 root disk 8, 19 Sep 8 18:52 sdb3 brw-rw---- 1 root disk 8, 20 Sep 8 18:52 sdb4 brw-rw---- 1 root disk 8, 21 Sep 8 18:52 sdb5 brw-rw---- 1 root disk 8, 22 Sep 8 18:52 sdb6 brw-rw---- 1 root disk 8, 23 Sep 8 18:52 sdb7 brw-rw---- 1 root disk 8, 24 Sep 8 18:52 sdb8 crw------- 1 root root 21, 0 Feb 9 14:47 sg0 crw------- 1 root root 21, 1 Feb 9 14:47 sg1 crw------- 1 root root 21, 10 Feb 9 14:47 sg10 crw------- 1 root root 21, 11 Feb 9 14:47 sg11 crw------- 1 root root 21, 12 Feb 9 14:47 sg12 crw------- 1 root root 21, 13 Feb 9 14:47 sg13 crw------- 1 root root 21, 14 Feb 9 14:47 sg14 crw------- 1 root root 21, 15 Feb 9 14:47 sg15 crw------- 1 root root 21, 16 Feb 9 14:47 sg16 crw------- 1 root root 21, 2 Feb 9 14:47 sg2 crw------- 1 root root 21, 3 Feb 9 14:47 sg3 crw------- 1 root root 21, 4 Feb 9 14:47 sg4 crw------- 1 root root 21, 5 Feb 9 14:47 sg5 crw------- 1 root root 21, 6 Feb 9 14:47 sg6 crw------- 1 root root 21, 7 Feb 9 14:47 sg7 crw------- 1 root root 21, 8 Feb 9 14:47 sg8 crw------- 1 root root 21, 9 Feb 9 14:47 sg9 crw--w--w- 1 root tty 4, 0 Sep 8 18:53 tty0 crw------- 1 root tty 4, 1 Feb 11 05:18 tty1 crw--w--w- 1 root root 4, 2 Feb 11 03:50 tty2 crw--w--w- 1 root root 4, 3 Feb 11 03:50 tty3 crw--w--w- 1 root root 4, 4 Feb 11 03:50 tty4 crw--w--w- 1 root root 4, 5 Feb 11 03:50 tty5 crw--w--w- 1 root root 4, 6 Feb 11 03:50 tty6 crw-rw-rw- 1 root tty 4, 7 Sep 8 18:53 tty7 cr--r--r-- 1 root root 1, 9 Feb 11 03:50 urandom lrwxrwxrwx 1 root root 4 Feb 17 15:32 vcs -> vcs0 crw------- 1 root root 7, 0 Sep 8 18:53 vcs0 crw------- 1 root sys 7, 1 Sep 8 18:53 vcs1 crw------- 1 root sys 7, 2 Sep 8 18:53 vcs2 crw------- 1 root sys 7, 3 Sep 8 18:53 vcs3 crw------- 1 root sys 7, 4 Sep 8 18:53 vcs4 crw------- 1 root sys 7, 5 Sep 8 18:53 vcs5 crw------- 1 root sys 7, 6 Sep 8 18:53 vcs6 crw------- 1 root root 7, 128 Sep 8 18:53 vcsa lrwxrwxrwx 1 root root 4 Feb 17 15:32 vcsa0 -> vcsa crw------- 1 root sys 7, 129 Sep 8 18:53 vcsa1 crw------- 1 root sys 7, 130 Sep 8 18:53 vcsa2 crw------- 1 root sys 7, 131 Sep 8 18:53 vcsa3 crw------- 1 root sys 7, 132 Sep 8 18:53 vcsa4 crw------- 1 root sys 7, 133 Sep 8 18:53 vcsa5 crw------- 1 root sys 7, 134 Sep 8 18:53 vcsa6 crw-rw-rw- 1 root root 1, 5 Sep 8 18:52 zero ./dos: total 0 ./etc: total 25 -rw-r--r-- 1 root root 82 Feb 11 13:58 bash.bashrc drwxr-xr-x 2 root root 1024 Feb 9 14:24 default -rw-r--r-- 1 root root 967 Feb 17 15:16 fstab -rw-r--r-- 1 root root 488 Feb 11 04:30 group -rw-r--r-- 1 root root 74 Nov 8 23:49 hexdump.fmt -rw-r--r-- 1 root root 6 Feb 6 02:30 hostname drwxr-xr-x 2 root root 1024 Feb 14 19:01 init.d -rw-r--r-- 1 root root 634 Feb 14 19:04 inittab -rw-r--r-- 1 root root 37 Feb 11 04:30 issue -rw-r--r-- 1 root root 1 Feb 11 04:40 ld.so.cache -rw-r--r-- 1 root root 1 Feb 11 04:44 ld.so.conf -rw-r--r-- 1 root root 39 Feb 10 15:17 mtab -rw-r--r-- 1 root root 1400 Feb 14 11:34 passwd -rw-r--r-- 1 root root 361 Feb 15 03:07 profile drwxr-xr-x 2 root root 1024 Feb 14 17:54 rc0.d drwxr-xr-x 2 root root 1024 Feb 14 17:55 rc1.d drwxr-xr-x 2 root root 1024 Feb 11 04:09 rc2.d drwxr-xr-x 2 root root 1024 Feb 14 17:56 rc3.d drwxr-xr-x 2 root root 1024 Feb 14 17:57 rc4.d drwxr-xr-x 2 root root 1024 Feb 14 17:57 rc5.d drwxr-xr-x 2 root root 1024 Feb 14 17:59 rc6.d drwxr-xr-x 2 root root 1024 Feb 14 19:02 rcS.d drwxr-xr-x 3 root root 1024 Feb 15 03:49 terminfo -rw-r--r-- 1 root root 11 Feb 11 06:01 timezone ./etc/default: total 2 -rw-r--r-- 1 root root 92 Nov 5 09:04 devpts -rwxr--r-- 1 root root 589 Feb 9 14:24 rcS ./etc/init.d: total 28 -rwxr-xr-x 1 root root 1934 Feb 14 18:17 bootmisc.sh -rwxr-xr-x 1 root root 731 Feb 11 04:05 checkfs.sh -rwxr-xr-x 1 root root 2943 Feb 11 04:05 checkroot.sh -rwxr-xr-x 1 root root 1087 Feb 11 04:05 devpts.sh -rwxr-xr-x 1 root root 281 Feb 11 04:05 halt -rwxr-xr-x 1 root root 132 Feb 11 04:05 hostname.sh -rwxr-xr-x 1 root root 395 Feb 11 04:05 isapnp -rwxr-xr-x 1 root root 561 Feb 11 04:05 mountall.sh -rwxr-xr-x 1 root root 1013 Feb 11 04:05 procps.sh -rwxr-xr-x 1 root root 2213 Feb 11 04:05 rc -rwxr-xr-x 1 root root 1190 Feb 11 04:05 rcS -rwxr-xr-x 1 root root 197 Feb 11 04:05 reboot -rwxr-xr-x 1 root root 252 Feb 11 04:05 rmnologin -rwxr-xr-x 1 root root 349 Feb 11 04:05 sendsigs -rwxr-xr-x 1 root root 476 Feb 11 04:05 single -rwxr-xr-x 1 root root 1471 Feb 11 04:05 sysklogd -rwxr-xr-x 1 root root 488 Feb 11 04:05 umountfs -rwxr-xr-x 1 root root 96 Nov 12 17:09 update -rwxr-xr-x 1 root root 1128 Feb 11 04:05 urandom ./etc/rc0.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 K90sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 18 Feb 17 15:32 S20sendsigs -> ../init.d/sendsigs lrwxrwxrwx 1 root root 17 Feb 17 15:32 S30urandom -> ../init.d/urandom lrwxrwxrwx 1 root root 18 Feb 17 15:32 S40umountfs -> ../init.d/umountfs lrwxrwxrwx 1 root root 14 Feb 17 15:32 S90halt -> ../init.d/halt ./etc/rc1.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 K90sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 16 Feb 17 15:32 S20single -> ../init.d/single ./etc/rc2.d: total 0 lrwxrwxrwx 1 root root 19 Feb 17 15:32 S99rmnologin -> ../init.d/rmnologin ./etc/rc3.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 19 Feb 17 15:32 S99rmnologin -> ../init.d/rmnologin ./etc/rc4.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 19 Feb 17 15:32 S99rmnologin -> ../init.d/rmnologin ./etc/rc5.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 S10sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 19 Feb 17 15:32 S99rmnologin -> ../init.d/rmnologin ./etc/rc6.d: total 0 lrwxrwxrwx 1 root root 18 Feb 17 15:32 K90sysklogd -> ../init.d/sysklogd lrwxrwxrwx 1 root root 18 Feb 17 15:32 S20sendsigs -> ../init.d/sendsigs lrwxrwxrwx 1 root root 17 Feb 17 15:32 S30urandom -> ../init.d/urandom lrwxrwxrwx 1 root root 18 Feb 17 15:32 S40umountfs -> ../init.d/umountfs lrwxrwxrwx 1 root root 16 Feb 17 15:32 S90reboot -> ../init.d/reboot ./etc/rcS.d: total 0 lrwxrwxrwx 1 root root 22 Feb 17 15:32 S10checkroot.sh -> ../init.d/checkroot.sh lrwxrwxrwx 1 root root 16 Feb 17 15:32 S15isapnp -> ../init.d/isapnp lrwxrwxrwx 1 root root 20 Feb 17 15:32 S30checkfs.sh -> ../init.d/checkfs.sh lrwxrwxrwx 1 root root 19 Feb 17 15:32 S30procps.sh -> ../init.d/procps.sh lrwxrwxrwx 1 root root 19 Feb 17 15:32 S35devpts.sh -> ../init.d/devpts.sh lrwxrwxrwx 1 root root 21 Feb 17 15:32 S35mountall.sh -> ../init.d/mountall.sh lrwxrwxrwx 1 root root 21 Feb 17 15:32 S40hostname.sh -> ../init.d/hostname.sh lrwxrwxrwx 1 root root 21 Feb 17 15:32 S55bootmisc.sh -> ../init.d/bootmisc.sh lrwxrwxrwx 1 root root 17 Feb 17 15:32 S55urandom -> ../init.d/urandom ./etc/terminfo: total 1 drwxr-xr-x 2 root root 1024 Feb 15 03:49 l ./etc/terminfo/l: total 2 -rw-r--r-- 1 root root 1563 Feb 15 03:49 linux ./extra: total 0 ./floppy: total 0 ./floppyB: total 0 ./home: total 1 drwxr-xr-x 2 root root 1024 Feb 15 03:11 craig ./home/craig: total 5 -rw-r--r-- 1 root root 810 Feb 15 03:53 .bashrc -rw-r--r-- 1 root root 217 Feb 15 03:10 .profile -rw-r--r-- 1 root root 2570 Feb 14 11:38 .vimrc ./lib: total 1377 -rwxr-xr-x 1 root root 83939 Feb 11 05:43 ld-2.1.3.so lrwxrwxrwx 1 root root 11 Feb 17 15:32 ld-linux.so.2 -> ld-2.1.3.so -rwxr-xr-x 1 root root 886932 Feb 10 16:18 libc-2.1.3.so lrwxrwxrwx 1 root root 13 Feb 17 15:32 libc.so.6 -> libc-2.1.3.so lrwxrwxrwx 1 root root 17 Feb 17 15:32 libcom_err.so.2 -> libcom_err.so.2.0 -rw-r--r-- 1 root root 5244 Feb 10 16:18 libcom_err.so.2.0 -rw-r--r-- 1 root root 9372 Feb 10 16:18 libdl-2.1.3.so lrwxrwxrwx 1 root root 14 Feb 17 15:32 libdl.so.2 -> libdl-2.1.3.so lrwxrwxrwx 1 root root 13 Feb 17 15:32 libe2p.so.2 -> libe2p.so.2.3 -rw-r--r-- 1 root root 12300 Feb 14 18:22 libe2p.so.2.3 lrwxrwxrwx 1 root root 16 Feb 17 15:32 libext2fs.so.2 -> libext2fs.so.2.4 -rw-r--r-- 1 root root 66000 Feb 10 16:18 libext2fs.so.2.4 lrwxrwxrwx 1 root root 17 Feb 17 15:32 libncurses.so.5 -> libncurses.so.5.0 -rw-r--r-- 1 root root 232780 Feb 10 16:18 libncurses.so.5.0 -rw-r--r-- 1 root root 19560 Feb 17 13:18 libnss_db-2.1.3.so lrwxrwxrwx 1 root root 18 Feb 17 15:32 libnss_db.so.2 -> libnss_db-2.1.3.so -rw-r--r-- 1 root root 31020 Feb 17 13:18 libnss_files-2.1.3.so lrwxrwxrwx 1 root root 21 Feb 17 15:32 libnss_files.so.2 -> libnss_files-2.1.3.so -rw-r--r-- 1 root root 33212 Feb 10 16:18 libproc.so.2.0.6 lrwxrwxrwx 1 root root 14 Feb 17 15:32 libuuid.so.1 -> libuuid.so.1.2 -rw-r--r-- 1 root root 7752 Feb 14 11:31 libuuid.so.1.2 drwxr-xr-x 2 root root 1024 Feb 10 16:41 locate drwxr-xr-x 3 root root 1024 Nov 8 18:04 terminfo ./lib/locate: total 19 -rwxr-xr-x 1 root root 5124 Feb 10 16:41 bigram -rwxr-xr-x 1 root root 6388 Feb 10 16:41 code -rwxr-xr-x 1 root root 5348 Feb 10 16:41 frcode ./lib/terminfo: total 1 drwxr-xr-x 2 root root 1024 Nov 8 18:04 l ./lib/terminfo/l: total 2 -rw-r--r-- 1 root root 1549 Nov 8 18:04 linux ./os2: total 0 ./proc: total 0 ./root: total 7 -rw-r--r-- 1 root root 810 Feb 15 03:52 .bashrc -rw-r--r-- 1 root root 1184 Feb 10 16:44 .mkisofsrc -rw-r--r-- 1 root root 217 Feb 15 03:08 .profile -rw-r--r-- 1 root root 2570 Feb 11 05:56 .vimrc ./sbin: total 373 -rwxr-xr-x 2 root root 75696 Feb 10 16:00 e2fsck -rwxr-xr-x 1 root root 85328 Feb 10 16:03 fdisk -rwxr-xr-x 2 root root 75696 Feb 10 16:00 fsck.ext2 -rwxr-xr-x 1 root root 7692 Feb 10 16:03 halt -rwxr-xr-x 1 root root 27720 Feb 10 16:03 init -rwxr-xr-x 1 root root 60016 Jan 22 06:37 insmod -rwxr-xr-x 1 root root 8756 Feb 10 16:03 killall5 lrwxrwxrwx 1 root root 6 Feb 17 15:32 lsmod -> insmod -rwxr-xr-x 1 root root 9440 Feb 17 15:30 mingetty lrwxrwxrwx 1 root root 6 Feb 17 15:32 modprobe -> insmod lrwxrwxrwx 1 root root 4 Feb 17 15:32 reboot -> halt lrwxrwxrwx 1 root root 6 Feb 17 15:32 rmmod -> insmod -rwxr-xr-x 1 root root 14828 Feb 10 16:03 shutdown lrwxrwxrwx 1 root root 4 Feb 17 15:32 telinit -> init -rwxr-xr-x 1 root root 5464 Feb 10 16:03 update ./tinyos2: total 0 ./tmp: total 0 ./usr: total 0 ./var: total 4 drwxr-xr-x 3 root root 1024 Feb 10 16:50 lib drwxr-xr-x 2 root root 1024 Feb 11 07:20 lock drwxr-xr-x 2 root root 1024 Feb 15 03:11 log drwxr-xr-x 2 root root 1024 Feb 14 19:14 run ./var/lib: total 1 drwxr-xr-x 2 root root 1024 Feb 10 16:50 locate ./var/lib/locate: total 0 ./var/lock: total 0 ./var/log: total 0 -rw-r--r-- 1 root root 0 Feb 14 11:43 daemon.log -rw-r--r-- 1 root root 0 Feb 14 11:43 debug -rw-r--r-- 1 root root 0 Feb 14 11:43 dmesg -rw-r--r-- 1 root root 0 Feb 14 11:43 faillog -rw-r--r-- 1 root root 0 Feb 14 11:43 kern.log -rw-r--r-- 1 root root 0 Feb 14 11:43 messages -rw-r--r-- 1 root root 0 Feb 14 11:43 syslog -rw-r--r-- 1 root root 0 Feb 15 03:11 wtmp ./var/run: total 1 -rw------- 1 root root 512 Nov 12 15:59 random-seed
Very few files are actually required, but quite a few are needed to do anything useful.
/dev is basically a look-up table between convenient device driver names and three items associated with each driver - a flag indicating whether it is a block or character device, its major number, and its minor number. The first two of these select the driver and the last tells it which particular channel is to be used. You only need to include devices for drivers you plan to use. For rescue diskettes, these include the console tty's, the floppy, hard disk and CD drives that might be accessed, the null and zero devices, loop devices, and ram disk devices. The symbolic links /dev/console and /dev/cdrom are expected by some programs.
Mounting parameters are held in /etc/fstab and /etc/mtab. These are manipulated by the programs /bin/mount and /bin/umount. /etc/fstab should be contain entries appropriate to your system. Mine contains:
# <file system> <mount point> <type> <options> <dump> <pass> / / ext2 defaults,errors=remount-ro 0 1 proc /proc proc defaults 0 0 /dev/sda2 /extra ext2 defaults,noauto 0 0 /dev/sda3 /dos msdos rw,noauto 0 0 /dev/sda5 /os2 hpfs ro,noauto 0 0 /dev/sda6 /tinyos2 hpfs ro,noauto 0 0 /dev/sda7 /backup ext2 defaults,noauto 0 0 /dev/sdb5 /biglinux ext2 defaults,noauto 0 0 /dev/cdrom /cdrom iso9660 ro,noauto,user,exec 0 0 /dev/fd0 /usr ext2 defaults,noauto,user,exec 0 0 /dev/fd0 /floppy ext2 defaults,noauto,user,exec 0 0 /dev/fd1 /floppyB ext2 defaults,noauto,user,exec 0 0
/etc/mtab should simply contain:
- / ext2 rw 0 0
which indicates that the root disk is already mounted by the time /etc/mtab can be read.
After the kernel has initialized itself, it looks for a program to run as "Process 1". This is nearly always /sbin/init, although in a dedicated system a custom program or /bin/bash might be run instead.
/sbin/init needs many supporting files starting with /etc/inittab which specifies scripts and programs to be run during its initialization and runlevel changing activities. The scripts are mostly in a directory init.d that is either in /etc (Sys-V init) or in /etc/rc.d (Another variety of init). An associated family of additional scripts and directories are also placed there or in the next higher directory. init also expects /var/run/utmp to exist.
The /etc/inittab file contains the following:
id:2:initdefault: si::sysinit:/etc/init.d/rcS ~~:S:wait:/sbin/sulogin l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now 1:2345:respawn:/sbin/mingetty tty1 2:23:respawn:/sbin/mingetty tty2 3:23:respawn:/sbin/mingetty tty3 4:23:respawn:/sbin/mingetty tty4 5:23:respawn:/sbin/mingetty tty5 6:23:respawn:/sbin/mingetty tty6
/sbin/init directly or indirectly invokes /sbin/update, /sbin/mingetty, /sbin/halt, /sbin/shutdown, /sbin/sulogin, /bin/date, /bin/e2fsck, and /bin/id plus various common utilities. I have not optimized these scripts for the floppy boot case - they still unnecessarily clean out /tmp and /var/run which are already clean.
The copy of mingetty used here has been specially modified to avoid using /sbin/login and passwords. The modified source is mingetty.c where a #define DIRECT_TO_SHELL turns on my changes. (The corresponding mingetty binary is included in the diskette imaged described below.) The modifications bypass password ceremonies, make an entry in /var/log/utmp, and run /bin/bash directly upon entering any user name given in /etc/passwd.
Common utilities for changing file permissions, listing files, working with partitions, etc., must be included. The program /bin/tput supports the /bin/tset utility which is in turn invoked by /bin/reset.
To support dynamic library loading, /lib/ld-linux.so, /etc/ld.so.cache, /etc/ld.so.conf, and /lib/libc.so are needed. The need for other libraries is discovered by running ldd on the various object modules in /bin and /sbin. /lib/terminfo/l/linux has been trimmed down to contain only one set of terminal parameters. /lib/locate contains files supporting the find and locate programs.
The directories under /var are expected by some programs. /var/lib/locate is where locatedb placed.
The shell program, /bin/bash, is configured by the following files /etc/profile, /root/.profile, and /root/.bashrc.
An editor is always needed. I like vim but it was too big to fit in with these other programs. It is on a third, "/usr" diskette described in the next section. There is still enough room on the root diskette for a small editor if you wish to add one. Remember to do an ldd on its executable to see what libraries it requires.
I also use a third diskette that I call my /usr diskette. It is to be mounted on /usr after the root filesystem has been loaded into RAM. It contains the following:
.: total 5 drwxr-xr-x 2 root root 1024 Feb 17 14:56 bin drwxr-xr-x 2 root root 1024 Feb 14 18:25 lib drwxr-xr-x 2 root root 1024 Feb 10 16:25 lost+found drwxr-xr-x 2 root root 1024 Feb 10 16:38 sbin drwxr-xr-x 3 root root 1024 Feb 14 19:57 share ./bin: total 1173 -rwxr-xr-x 1 root root 158544 Feb 10 16:28 cdrecord -rwxr-xr-x 1 root root 205788 Feb 10 16:27 ldconfig -rwxr-xr-x 1 root root 147568 Feb 10 16:27 mkisofs -rwxr-xr-x 1 root root 127312 Feb 10 16:00 tar lrwxrwxrwx 1 root root 3 Feb 14 11:30 vi -> vim -rwxr-xr-x 1 root root 551216 Feb 10 16:27 vim ./lib: total 0 ./lost+found: total 0 ./sbin: total 0 ./share: total 1 drwxr-xr-x 3 root root 1024 Feb 14 19:58 vim ./share/vim: total 1 drwxr-xr-x 3 root root 1024 Feb 14 20:05 vim56 ./share/vim/vim56: total 6 drwxr-xr-x 2 root root 1024 Feb 14 20:08 syntax -rw-r--r-- 1 root root 4801 Feb 14 20:05 vimrc ./share/vim/vim56/syntax: total 7 -rw-r--r-- 1 root root 5544 Feb 14 20:08 synload.vim -rw-r--r-- 1 root root 955 Feb 14 20:04 syntax.vim
This diskette still has some room for additional goodies. The most important items on this diskette are vim and tar. cdrecord and mkisofs are used to make backups to CD-ROM.
Last updated: April 10, 2006
Contact Craig Van Degrift if you have problems or questions with this web site.