Linux on a single floppy disk

Adam Jensen <ajensen@linuxguy.org>
January 1, 2008

This document outlines the steps needed to build a Linux- and HostAP-based router that fits on a single floppy disk.

This is intended to be a guide, providing an overview of the necessary steps to build a functioning disk image. I do not have the time or resources to provide support for this guide. On the other hand, if you have comments regarding this work, or if you notice a mistake, please e-mail me at the address listed above.

For reference, I have made my disk image available:

N.B.: Due to the size of this image, the floppy device node /dev/fd0u1722 (or equivalent) must be used when writing the images to disk. For a discussion of this, please see ``Building the Final Disk Image''.

Motivation

I maintain a network that consists of three buildings, each with its own set of computers. Between two of these buildings is a wireless link that spans 1/8 mile, and there is a headless Linux-based PC at each end to handle routing and management of wireless clients. The software that powers these machines is the focus of this work.

Goals

My intent was to build a Linux distribution that fits on a single 1.44MB floppy disk and has the following features:

Building such a distribution is not difficult, but it took me some time to work out all of the details. The paragraphs that follow should contain enough substance to give the reader a sense of what needs to be done.

Software Used

All work was performed on a PC running Ubuntu Linux 7.10.

Setting up the kernel

The latest stable kernel at the time of this writing is 2.6.23.12. My .config file is available for anyone who is curious about the chosen configuration or would like to start with a small set of enabled features.

After building the kernel (using make), running make bzdisk with a floppy disk in the drive will produce a bootable floppy disk that includes the freshly-built kernel. Respectively, one can use make fdimage to produce an image file that can be written to a floppy disk later.

The image can be written to disk using

dd if=<source image> of=/dev/fd0u1722

and the new disk can be mounted as follows:

mount /dev/fd01722 /mnt

We need to modify the /mnt/syslinux.cfg file in order to use the root filesystem that we will create in the next section. The following line must be added to the end of the file:

append initrd=rootfs.gz root=/dev/ram0

The file rootfs.gz is the compressed root filesystem. To the kernel, this is the initial ramdisk (initrd) that contains the tools and scripts that will bring the system into a usable state after all necessary drivers have been loaded. How to create and populate this filesystem is covered next.

Setting up the root filesystem

In addition to the kernel, we need a root filesystem. The following commands will create a file called rootfs that contains an empty ext2 filesystem.

dd if=/dev/zero of=rootfs bs=1k count=1722
mkfs.ext2 -i 1024 -m 0 rootfs

The filesystem can be mounted as follows:

mount -o loop rootfs /mnt

Populating the filesystem

At this point, the filesystem needs to be populated. I recommend starting with a skeleton filesystem such as the one available from IBM's developerWorks tutorial [1]. The uClibc shared libraries need to be copied into place as well (typically into /lib), along with the BusyBox binary and symlinks that were produced by the uClibc toolchain.

Further configuration

Any kernel modules that were built earlier will also need to be part of this root filesystem. These modules must be loaded by a custom script, since the base system provides no mechanism to automate this. The modules are normally placed in /lib/modules/2.6.23.12 for the version of the Linux kernel that we're using here. Further configuration, such as network setup and DHCP server startup must also be performed using a script.

Building the final disk image

At this point, it is assumed that we have a bootable floppy disk containing our kernel of choice and a root filesystem that contains all of the tools, files, and kernel modules that we need.

First, we compress the root filesystem to save space:

gzip -v9 -c rootfs > rootfs.gz

A note about disk size and formatting: the standard 1.44MB afforded by floppy disks was not enough to build the distribution that I needed. However, most floppy disks can be formatted well beyond their stated capacity. On a modern Linux system, the device /dev/fd0u1722 (for example) allows a disk to be formatted to 1.722MB. To pursue this option, the alternate device should be used instead of fd0. (If the /dev/fd0u1722 device file does not exist on your system, you can create it with mknod /dev/fd0u1722 b 2 60)

Assuming that our floppy disk is mounted on /mnt, we copy the filesystem to the disk:

cp rootfs.gz /mnt/rootfs.gz

At this point, the disk is ready to be used.

Testing the disk image

Verifying that our disk-building work was successful can become tiresome. The cycle of modifying files, saving the image, writing the image to disk, and transferring the disk to the target system can be simplified using some simple tools. Shell scripts can automate the disk mounting and file copying, and the excellent processor emulator QEMU will allow the image to be tested on a workstation without requiring a reboot. This allows us to test the disk image on the same machine that was used to develop it, allowing greater flexibility in the development process.

References

[1] IBM developerWorks: Lightweight Linux. http://www.ibm.com/developerworks/linux/library/l-lwl1/.

Revision history


7/14/2008: Removed syslinux image due to reported problems.
3/13/2008: Corrected the device nodes used when writing disk images.
2/26/2008: Updated original disk image and posted new image based on EXTLINUX.
2/21/2008: Fixed BusyBox link. Reworded introduction to be clearer about disk format.


Please send comments to ajensen@linuxguy.org.
Last modified 2/26/2008