Linux system on a floppy

If this document happens to help you and you're feeling generous consider getting something from my Amazon wishlist

Useful Links

Take a look at my updated Linux Floppy Howto. I have been updating this slowly as I have been builting my new floppy firewall disk. This document aims to be easier to follow and more useful in creating a floppy that can be added to and configured more extensively.

For those who want to get a quick start try my linux floppy template called the tclDisk just configure it and go.

Updates

Dec 23, 2004: Made a couple small changes for consistency sake
May 10, 2004: My updated page now includes instructions for putting images on CDs.
Apr 08, 2004: Made a small addition to troubleshooting section
Nov 13, 2003: Added links for my tclDisk page and moved old changes to the end of the page.

Overview

This document outlines one way in which to create functional GNU/linux distribution which fits on a single floppy (or any other media for that matter).

Sections

Compile a kernel
Place the kernel on a floppy
Create a root filesystem
Put applications on the root filesystem
Place the root filesystem on the floppy
Set kernel boot parameters
Test the floppy
Troubleshooting
References (aka places to go for help)
Example floppy image

Compile a Kernel

First thing to do is to compile the kernel to be used on your floppy. If you do not know how to compile a kernel take a look at the
the kernel howto (later I may put up my own simplified version). Due to the limited space on floppies it is best to compile only the needed options.
In this document I will be focusing on using the linux kernel v2.4. Although the process is similar for 2.2 special considerations must be made for /dev (basically you must manually create the device files at some point).

Required Kernel configuration

Code maturity level->Prompt for development
Processor type and features->Support for your processor
General setup->kernel support for ELF binaries
Block devices->Normal PC floppy disk support
  • or else support for the device you will boot from
    Block devices->RAM disk support
  • I usually keep the size at 4096 (4MB)
    File systems->/proc filesystem
    File systems->/dev file system support
    File systems->Automatically mount at boot (option under devfs) (This is often overlooked but is normally the cause for console errors)
    File systems->Second extended fs (or use minix to save some space)
    Character devices->Virtual terminal
    Character devices->Support for console on virtual terminal
  • if your really need to save space and don't need console support you can leave this out (just make sure you have it working before you take this away.)
    Console drivers->VGA text console
  • this too can be removed once you are sure thing work

    Optional Kernel configuration

    General setup->PCI support
  • for network cards, etc.
    (kernel 2.4)Networking options->Network packet filtering
    (2.4)Networking options->IP: Netfilter Configuration->Connection tracking
    (2.4)Networking options->IP: Netfilter Configuration->IP tables support
    (2.4)Networking options->IP: Netfilter Configuration->Full NAT
    (2.4)Networking options->IP: Netfilter Configuration->MASQUERADE target support
    Network device support->Your Network device
    Network device support->PPP
    Network device support->PPP *
  • If ppp is required
    Character devices->Standard/generic
  • for modem support
    Character devices->Unix98 PTY
  • for pppd use
    Sound->Sound card drivers (mp3 jukebox)

    Disable

    General setup->PCI device name database (saves about 80kb)
  • and anything else which is not needed will save space.

    Compiling Kernel

    After you've configured the kernel and compiled it
    make dep bzImage

    You now have a kernel compiled and (most likely) located at /usr/src/linux/arch/i386/boot/bzImage

    Place the kernel on a disk

    Now we will take the bzImage and place it at the beginning of the floppy disk. The following command takes the kernel and writes it directly to the front of the disk.
    dd if=/usr/src/linux/arch/i386/boot/bzImage of=/dev/fd0 bs=1k
    
    Make sure you note the number or records returned from the dd command (for example 388+1). This will be needed later.

    The floppy now looks like
    KERNEL
    In this example the kernel now occupies the disk from byte 0 to byte 388. Remember this number because later will will want to add the root filesystem to the disk soon after it. So for this example maybe we want to remember 400 this will leave us a little room (marked with X) in case we need to add something else to the kernel later.

                         / 400k
    -------------------------------------------------------------
    |    bzImage      |X| Root Filesystem ( coming soon)        |
    -------------------------------------------------------------
    0            388k/                                       1.44MB
    

    Root Filesystem

    First create an empty file which will hold the root filesystem filled with zeros to maximize compression.
    dd if=/dev/zero of=disk.ext2 bs=1k count=4096
    Next make the file into a ext2 filesystem.
    mke2fs -Fm0 disk.ext2
    Now mount the new filesystem
    mount disk.ext2 /mnt/floppy -o loop
    If this returns an error you might not have loopback support in the kernel

    Remove lost+found from /mnt/floppy as it is not needed.

    rmdir /mnt/floppy/lost+found
    Create directories
    cd /mnt/floppy
    mkdir -p etc/init.d bin sbin dev proc usr/bin usr/sbin var/lock tmp lib
    

    Create the /mnt/floppy/etc/fstab file containing

    none                    /proc                   proc    defaults        0 0
    

    Put programs on the disk

    Now to actually put some useful application on the root filesystem...

    Choices

    Most linux on a floppy distributions include module support for devices so that you can just copy a module file into the right directory for support. I usually just disable module support and compile everything that I use into the kernel. It's up to you whether you want the expand-ability provided by modules or the simplicity and speed provided by compiling things into the kernel.

    In creating this floppy you can either compile packages statically or dynamically. A static program will be larger than its dynamic counterpart because it will compile all the needed functions into a single executable. A dynamic executable on the other hand is smaller because it links to an external library which contains certain functions. With dynamic libraries different programs can share a common library to save space. For simplicity sake I will explain only the dynamically linked method. If you would have problems with static executables email me and I will try to help out.

    uClibc

    Download
    uClibc (I used version 0.9.9). In the Config file make sure the following are set
    SHARED_LIB_LOADER_PATH=/lib
    DEVEL_PREFIX = /usr/$(TARGET_ARCH)-linux-uclibc
    SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)/usr
    
    That will make sure all the uClibc libraries and applications stay under /usr/i386-linux-uclibc/
    After making and installing uclibc you can compile other applications to link with it using /usr/i386-linux-uclibc/bin/cc.
    To use files linked against uclibc on the floppy make sure to copy the following files to /lib on your root file system.
    cp /usr/i386-linux-uclibc/lib/ld-uClibc.so.0 /mnt/floppy/lib
    cp /usr/i386-linux-uclibc/lib/libc.so.0 /mnt/floppy/lib
    
    These also are required by some applications (remember you can always find out what libraries an app needs by executing /usr/i386-linux-uclibc/bin/ldd <program>)
    /usr/i386-linux-uclibc/lib/libcrypt.so.0
    
    and any other libraries you may need.

    Busybox

    Now to put the basic system programs on the disk I use Busybox which implement various GNU utilities in one small executable. The beauty of this program is that you can compile in only the utilities you want. Also you can run a program as busybox <command> or just create a symlink from busybox to <command> and you can run the command like normal.

    To compile busybox using uclibc make sure the following is set in busybox's Makefile

    DOSTATIC = false
    CC=/usr/i386-linux-uclibc/usr/bin/i386-uclibc-gcc
    
    Also make sure the following are set in Config.h
    #define BB_INIT
    #define BB_MOUNT
    
    #define BB_FEATURE_INSTALLER
    #define BB_FEATURE_DEVFS
    
    Be sure to uncomment any other apps that you may need, for example a shell (e.g. MSH), ifconfig, route, vi, etc.
    If you are using kernel modules make sure to uncomment the following useful apps
    #define BB_INSMOD
    #define BB_LSMOD
    #define BB_MODPROBE
    #define BB_RMMOD
    #define BB_FEATURE_NEW_MODULE_INTERFACE // for post 2.1 kernels
    

    Now compile busybox make To put busybox on the root filesystem do the following

    cp busybox /mnt/floppy/bin
    
    Now create some links to necessary system programs.
    cd /mnt/floppy/sbin
    ln -s ../bin/busybox init
    ln -s ../bin/busybox modprobe # if you are using kernel modules
    cd ../bin
    ln -s busybox sh
    ln -s busybox mount
    
    You could create all the links for the busybox programs manually but busybox actually includes a nifty option (--install -s) which will create all the links for you. We just need to call busybox --install -s from a startup script which I will describe in the next section

    iptables

    To compile iptables modify the following directives in the Makefile to match this
    LIBDIR:=/lib
    BINDIR:=/sbin
    
    comment out the check for IPv6 (uClibc webpage mentions it not working yet)
    #ifeq ($(shell [ -f /usr/include/netinet/ip6.h ] && echo YES), YES)
    #DO_IPV6=0
    #endif
    
    and use the following command in the iptables source directory to compile it linked to uClibc.
    CC=/usr/i386-linux-uclibc/bin/cc make
    
    Copy the iptables binary to /mnt/floppy/sbin on your root file system and then create the directory /mnt/floppy/lib/iptables/ on the root filesystem. Copy the .so files from the extensions directory in the iptables source directory to /mnt/floppy/lib/iptables/.

    After the kernel boots it will uncompress the root image into ram and mount it read-only. It will then look for /sbin/init to execute. This in effect runs busybox as init which looks for the file /etc/init.d/rcS to execute.

    So create /mnt/floppy/etc/init.d/rcS containing

    #!/bin/sh
    mount /proc          # needed by the busybox --install command
    busybox --install -s     # creates links to all the busybox applets
    
    # Other commands for startup 
    # e,g, ifconfig eth0 192.168.1.1
    
    and make it executable
    chmod +x /mnt/floppy/etc/init.d/rcS

    Now unmount the root filesystem

    umount /mnt/floppy
    
    Compress the disk image (-9 for best compression)
    gzip -9 disk.ext2
    
    And write it to the floppy remember the location where the kernel image ended and add a little extra buffer space (if so desired). In this example I assume the kernel takes up the first 388k so I will start the root at 400 to allow for a little large kernel later.

    Copy the root filesystem to the disk

    dd if=disk.ext2.gz of=/dev/fd0 bs=1k seek=400
    
    May need to add conv=notrunc for linux 2.4 if you get a permission denied error on fd0

    Configure boot parameters

    This tells the kernel what device contains its root filesystem.
    rdev /dev/fd0 /dev/fd0
    This tells the kernel where on the device the root filesystem is located.
    rdev -r /dev/fd0 16784
    The value 16784 is equal to 16384 (2^14 which tells kernel to load ramdisk) + 400 (location of root filesystem on root device)
    The rdev -r value should be equal to the sum of the offset of the root filesytem image and the following options you desire.
    16384 - Use the ramdisk
    32768 - Prompt for root disk
    
    This tells the kernel to mount the root filesystem read-write instead of read-only (which would be normal on a system with a harddrive as the root filesystem).
    rdev -R /dev/fd0 0

    Test the disk

    Now boot a machine with the floppy and see if there are any problems.

    OR

    I have been able to boot my linux floppy with bochs an open source IA-32 (x86) PC emulator. This is the .bochsrc that I use

    # configuration file generated by Bochs
    floppya: 1_44="floppy.img", status=inserted
    # no floppyb
    # no diskc
    # no diskd
    # no cdromd
    romimage: file=bios/BIOS-bochs-latest, address=0xf0000
    vgaromimage: bios/VGABIOS-elpin-2.40
    megs: 32
    # no parport #1
    # no sb16
    boot: a
    vga_update_interval: 30000
    keyboard_serial_delay: 20000
    #floppy_command_delay: 50000
    floppy_command_delay: 5000
    ips: 500000
    mouse: enabled=0
    private_colormap: enabled=0
    i440fxsupport: enabled=0
    time0: 0
    # no ne2k
    newharddrivesupport: enabled=1
    # no loader
    log: -
    panic: action=ask
    error: action=report
    info: action=report
    debug: action=ignore
    
    Just make sure to change floppy.img to the name of your floppy image.

    To make an image without using a floppy disk use the following commands.
    For <SIZE> us the size reported by 'du -k bzImage' plus approx 5.

    dd if=bzImage of=floppy.img bs=1k
    dd if=disk.ext2.gz of=floppy.img bs=1k seek=<SIZE>
    rdev floppy.img /dev/fd0
    rdev -R floppy.img 0
    rdev -r floppy.img `expr 16384 + <SIZE>`
    
    Once you have tested this floppy.img you can always put it on a floppy disk with
    dd if=floppy.img of=/dev/fd0

    Specific Projects

    XFree86 KDdrive Server (a tiny X implementation)

    download the latest source for XFree86
    This should compile with uclibc but I have not done it yet myself. I should have it done in a week or so though. Add (or create) the following in xc/config/cf/host.def
    #define BuildServersOnly YES
    #define ProjectRoot /usr/bin
    #define KDriveXServer YES
    #define XfbdevServer YES
    #define XvesaServer YES
    

    Troubleshooting

    Just a few problems people have had creating a linux floppy and possible solutions.

    Problem:

    You get only "Loading linux....."

    Solutions

    Solution 1: I have read that this may be related to some BIOS having problems booting a bzImage. Try doing make zImage instead.
    Solution 2: Make sure the following are compiled into the kernel
    Character devices->Virtual terminal
    Character devices->Support for console on virtual terminal
    Console drivers->VGA text console
    

    Problem:

    Upon booting busybox reports
    device 'dev/tty2' not found
    device 'dev/tty3' not found
    

    Solution:

    Make sure to uncomment #define BB_FEATURE_DEVFS in the Config.h of busybox.

    Problem:

    During boot kernel reports
    warning: unable to open an initial console
    

    Solution:

    Make sure you have enabled the following option in the kernel config
    File Systems->Automatically mount at boot (sub option of devfs)
    

    Problem:

    Kernel reports ...
    Kernel panic: No init found. Try passing init= option to kernel.
    

    Solutions:

    I'll assume the kernel reports it has mounted the root filesystem successfully.
    VFS: Mounted root<fstype> filesystem)...
    
    If so I would check to make sure that init is located in the correct place the root filesystem and that it is executable. These seem to be the two most often occuring problems which cause that error. init should be /sbin/init and be chmod 755. If you happen to have the root filesystem somewhere on a linux machine I recommend checking it like this.
    mount rootfs /mnt/floppy -o loop
    ls -l /mnt/floppy/sbin/init
    # mine is a symbolic link to busybox
    > lrwxrwxrwx 1 root root 14 Jan 13 23:45 /mnt/floppy/sbin/init->../bin/busybox
    ls -l /mnt/floppy/bin/busybox
    > -rwxr-xr-x 1 root root 256524 Jan 11 13:24 /mnt/floppy/bin/busybox
    # Notice it is executable
    
    If yours is not located in /sbin/init, is not linked to busybox, or is not executable I would fix those and try again.

    Another problem that could cause this is that the init binary is linked to libraries which are not in the correct place on the floppy. After mounting the root image perform an ldd (using the uClibc ldd) on bin/busybox. The libraries it points to should be on the root image and in their proper locations. Note the SHARED_LIB_LOADER_PATH option mentioned above for uClibc to force the shared library loader to look in /lib for it's libraries.

    Hope this helps. There may be a few more advanced problems which could be causing that error but I figured I should cover the bases first.

    References

    I found most of this info from ramdisk.txt Paul Gortmaker's document in the linux src tree. Look for /usr/src/linux/Documentation/ramdisk.txt
    Also look at
    The Linux BootDisk HOWTO
    Email me at bkeffer.web(at)thecommandline.org and I will try to help as best I can.

    Example Linux Floppy Image

    A have noticed that on some machines (most of them Dell's) that these floppies will just reboot as soon as linux starts booting. I am looking into that and will try to fix is soon. If you know why this hapens please let me know.

    Rescue Floppy with support for Adaptec AIC7xxx, EtherExpress Pro 100, 3C509, 3C59x, NTFS, Reiserfs,USB keyboards, and more.
    Rescue Floppy v2 with support for Adaptec AIC7xxx, EtherExpress Pro 100, 3C509, 3C59x, NTFS, Reiserfs,USB keyboards, and more. This version includes mkfs utilities for dos, minix, ext2, and ext3.
    Floppy v3 with support for Adaptec AIC7xxx, EtherExpress Pro 100, 3C509, 3C59x, NTFS, Reiserfs,USB keyboards, and including a http daemon. With this image you can start networking and run 'cd /;httpd' to serve your entire computer as a web site. I'm not sure how to allow for directory listings yet but you can access http://192.168.1.2/dev/discs/dics0/disc to make an image of a disk. All you need is a machine with a browser.
    And to restore the image to the machine you can use wget which is also on the floppy. I will try to automate some of the process when I get a chance, e.g. it would be nice if the floppy booted, ran the included dhcp client (or asked for the ip if that fails), starts the web server, and creates a default webpage listing all the available devices on the computer.
    Syslinux floppy 0.2 is a syslinux floppy disk (msdos formatted) so you can add and remove parts easier. It currently only supports a few 3com nics, the intel EtherExpressPro100, and Pegasus based USB nics. I hope to include modules soon and distribute those along with the floppy. The floppy will boot, attempt to get an address via dhcp, then will untar the file bin.tgz from the floppy placing its contents into /usr/local/bin. My plan with this is to have modules which can be placed into a file caled modules.tgz, binarys in bin.tgz, a startup script in local.rc, and a configuration file that sets some options (like static ip vs dhcp and other things). This way people can modify the floppy much more. Hopefully I will have more of this done in the next month.
    Syslinux floppy template is a tarball with a syslinux floppy disk (msdos formatted) and most the components which went into creating it. There are currently no instructions yet but you should be able to follow my updated floppy howto and understand how to use this to make your own floppy. For the impatient you should be able to dd the file floppy.img from this tarball to a disk which will give you a syslinux floppy that will execute a script called rc.d on the floppy. This disk also has iptables and module support so you script could load a network module and a firewall if you like. For those who want to tweak more the tarball includes the root filesystem shell used to create the minix root filesystem, the kernel, and the kernel config which was used. I will try to improve it when I get a chance but for now take a look at my updated floppy page.
    Latest Version of the tcldisk. The beginnings of a README included.

    To put this on a floppy
    Linux: dd if=rescue1.img of=/dev/fd0
    Windows: Use Rawrite

    Changes History

    Nov 9,2003: Those looking for a quick and easy way to get started using a linux floppy take a look at my tclDisk page. It is a bare minimum linux floppy with networking support and room to grow.

    Oct 21, 2003: Most of my recent floppy work has been on my Updated Floppy HOWTO but I added a link to my template floppy tarball on the bottom of this page. It simplifies some of the work required to make a floppy disk.

    Jun 30, 2003: I have added another problem/solution about the message 'Kernel panic: No init found. Try passing init=option to kernel. '. Someone at nasa emailed me this question but my reply messages kept getting bounced back, so I hope you find this.

    Jun 27, 2003: Since moving to my new server the floppy forum has been removed. So if you want instructions for syslinux take a look at the Beta Floppy HOWTO (I may put a new one up sometime though)

    Apr 28, 2003: I fixed the link to the latest floppy (syslin2.img) at end of this document, I had made a relative link when it should have been absolute. I should have seen it sooner.

    Apr 22, 2003: Here is a link to the updated linux floppy document I am working on. Hopefully it will become more clear and polished then my current one. Right now it is just a mix of old information along with notes to myself about what to write but I will eventually have step by step instructions for creating syslinux floppy disks (in addition to the simpler method outlined here) which will hopefully lay a ground work for bootable linux CDs and more expandable linux disks.

    Feb 5, 2003: Added a link to latest floppy disk. This is a syslinux disk created using a different method than the one below. It allows for easier addition of programs (now) and modules (soon). Syslinux floppy 0.2 is the latest release, I will add instructions for building a syslinux floppy soon. For now take a look at this here for basic instructions on creating a syslinux disk (you can use the root image and kernel as created from the following instructions).

    Sep 10, 2002: I have added a new floppy image with an httpd daemon and various files systems support.

    July 9, 2002: Updated link for Linux BootDisk HOWTO, emphasized Auto mount devfs

    July 4, 2002: Fixed a few typos (e.g. mkdir /lib -> mkdir lib) thanks pogo

    Mar 23, 2002: Added more help on using kernel modules.

    Mar 20, 2002: Added rescue2.img linux floppy image. This version has mkfs utilities for formating dos, ext2, ext3, and minix partitions. The next version (coming soon) will have reiserfs support and a hard disk partitioning program too.
    -- Oh and I added an updates section.

    Mar 17, 2002: Rewrote some sections and changed the flow of the instructions.

    Mar 3, 2002: Added instructions for getting bochs to boot floppy images.