A Recipe for creating a bootable Linux Floppy Disk

What ingredients do we need?

Getting our ingredients

Prepping our ingredients

Create a directory off your home directory, call it myboot. Download the files into your myboot directory using the wget command or just download using the links above in your browser. For each file, right click the link and then type in the terminal wget [PRESS SHIFT-INS]. Here's what my /home/clarkbw/myboot directory now looks like:

-rw-r--r--  1 clarkbw users 753K Apr 18 15:40 busybox-0.60.3.tar.gz
-rw-r--r--  1 clarkbw users 3.0M Apr 18 15:39 e2fsprogs-1.34.tar.gz
-rw-r--r--  1 clarkbw users  34M Apr  3 23:16 linux-2.4.25.tar.bz2
-rw-r--r--  1 clarkbw users 1.5M Apr 18 15:42 uClibc-0.9.21.tar.bz2
-rw-r--r--  1 clarkbw users 1.8M Apr 18 15:40 util-linux-2.12.tar.gz
	

So lets unpack all the tarballs that we have now so we can begin to work with them. You can use the following commands to unpack them all.

		
	for f in `ls *.bz2`; do
		tar -jxvf $f
	done
	for f in `ls *.gz`; do
		tar -zxvf $f
	done
		
	

Prepping the Kernel

From your myboot, go into the kernel directory cd linux-2.4.25. We first need to configure the kernel to be the most minimal kernel we can make. To do this we'll edit the kernel configuration and turn off most things. make menuconfig. This will bring up a ncurses screen where we can edit the kernel configuration to make the changes we need.

Exit out of the menu and choose YES to save your configuration Now we need to compile this kernel.

		
	make clean
	make dep
	make
	make bzImage
		
	

Prepping uClibc

In the uClibc we're going to setup the config files to the correct system and locations. First, in your myboot directory create the following directories: mkdir uclibc-dev rootfs Then cd into the uClibc directory and type: make menuconfig and make sure you configure the following options.

Replace the $USER variable with your username.

Now make and install the uClibc package.

		
	make
		
	

There's an error in either the Makefile or something with the sed script which caused a build fail on my box. If it fails on build you'll need to do this:

  cd /home/$USER/myboot/uClibc-0.9.21/libc/sysdeps/linux/i386
  gcc  -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -mpreferred-stack-boundary=2 -falign-jumps=0 -falign-loops=0 -Os -fno-builtin -nostdinc -D_LIBC -I../../../../include -I. -I/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.3/include -DNDEBUG -fPIC -c ../common/gmon-start.c -S -o gmon-start.S	
	

Now do make again in the main directory.

	cd -
	make
	make install
	make PREFIX=/home/$USER/myboot/rootfs install_target
	

Prepping BusyBox

First we'll cd into the busybox directory, then we'll be editing the Config.h file. If you'd like to have more programs or features you can uncomment whatever you see fit in this file. One line that needs to be uncommented is the BB_FEATURE_USE_TERMIOS.

In the Makefile append -mcpu=i386 to the CFLAGS_EXTRA variable. Down further, uncomment and change the definition of the SECOND CC variable location. Enter CC = /home/$USER/myboot/uclibc-dev/bin/i386-uclibc-gcc.

You'll need to patch the BusyBox source code with this patch, open up the init.c file and replace the line with the minus with the line with the plus.

--- init.c      2004-04-19 10:23:31.336806304 -0400
+++ init.c~     2004-04-19 10:20:47.043782640 -0400
@@ -768,7 +768,7 @@
                        execl(a->command, a->command, NULL);
  
                        message(CONSOLE|LOG, "\rexec of '%s' failed: %s\n",
+                               a->command, strsignal(errno));
-                               a->command, sys_errlist[errno]);
                        sync();
                        sleep(2);
                        init_reboot(RB_HALT_SYSTEM);
	
	

You'll need to do this several times in the ash.c file, look for sys_siglist[] and replace with strsignal()

		
	make
	make PREFIX=/home/$USER/myboot/rootfs install
		
	

To use the BusyBox environment we'll have to change root's like this: /usr/sbin/chroot /home/$USER/myboot/rootfs /bin/sh

This will put our terminal in the busybox environment as it is expecting everything to be setup. Since we've dynamically linked all our libraries the busybox tools are looking to /lib for all of the libraries, but they actually exist in /home/clarkbw/myboot/rootfs/lib. When you're done checking out the busybox environment you can type exit to quit.

Prepping Other Utils

First we need a new terminal for the next part, so right click on the terminal space and choose "Open Terminal". This should give you a new terminal in the same path as the old one. Now we'll setup the environment of the new terminal with this command: export PATH=/home/$USER/myboot/uclibc-dev/bin:$PATH

Cd into the util-linux directory and open up the MCONFIG file. Edit the CFLAGS variable, add -D__NO_CTYPE \ to the second to last line of the CFLAGS variable definition.

Now we'll build all the utilities even though we only need the fdisk utility and nothing else.

	make
	mkdir ../rootfs/sbin
	cp fdisk/fdisk ../rootfs/sbin
	

Next, cd into the e2fsprogs directory and run configure and make.

	./configure
	make
	

Now that we've compiled succesfully we'll take only the programs we need and leave the rest behind.

	strip e2fsck/e2fsck.shared
	cp e2fsck/e2fsck.shared ../rootfs/sbin/e2fsck
	strip misc/mke2fs
	cp misc/mke2fs ../rootfs/sbin/
	

Prepping our Root File System

Now that we have most of the binaries we need to get the system up and running we'll need to setup our root filesystem.

	cd /home/$USER/myboot/rootfs
	mkdir dev tmp etc proc mnt etc/init.d
	

We need to be root to make device nodes, so we'll wait until we've booted off our floppy disk before we try to do this. For now we can make a script out of it, just copy the contents into a file and call it rcS and put in /home/$USER/myboot/rootfs/etc/init.d/ Remeber to make it executeable by running this command: chmod +x /home/$USER/myboot/rootfs/etc/init.d/rcS

#!/bin/sh

mount -t proc none /proc
chown -R 0:0 /

As root run the following commands

cd /home/$USER/myboot/rootfs/dev
mknod fd0 b 2 0
mknod fd1 b 2 1
mknod hda b 3 0
mknod hda1 b 3 1
mknod hda2 b 3 2
mknod hda3 b 3 3
mknod hda4 b 3 4
mknod hda5 b 3 5
mknod hda6 b 3 6
mknod hda7 b 3 7
mknod hda8 b 3 8
mknod hdb b 3 64
mknod hdb1 b 3 65
mknod hdb2 b 3 66
mknod hdb3 b 3 67
mknod hdb4 b 3 68
mknod hdb5 b 3 69
mknod hdb6 b 3 70
mknod hdb7 b 3 71
mknod hdb8 b 3 72
mknod tty c 5 0
mknod console c 5 1
mknod tty1 c 4 1
mknod tty2 c 4 2
mknod tty3 c 4 3
mknod tty4 c 4 4
mknod ram b 1 1
mknod mem c 1 1
mknod kmem c 1 2
mknod null c 1 3
mknod zero c 1 5
	

Prepping our Boot Disk

First we need to create a RAM disk that we'll use. The RAM disk will be loaded into RAM by the kernel on bootup and the system will start from there.

	dd if=/dev/zero of=/home/$USER/myboot/root.img \
	bs=1k count=1000
	/sbin/mke2fs -F -N 200 /home/$USER/myboot/root.img
	mkdir /home/$USER/myboot/mnt
	

Save the following file in your myboot directory as grubfd.conf.

#                                                                                          
# /etc/grubfd.conf - make a floppy boot disk                                               
#                                                                                          
# To install grub on the floppy, issue the following command:                              
#  grep -v ^# /etc/grubfd.conf | grub --batch                                              
#                                                                                          
root (fd0)                                                                                 
install /boot/grub/stage1 d (fd0) (fd0)/boot/grub/stage2 0x8000 p (fd0)/boot/grub/menu.lst 
quit	
	

Save the following as menu.lst in your myboot directory.

default 1
timeout 10

title=Boot Floppy
root (fd0)
kernel (fd0)/boot/bzImage root=/dev/ram
initrd=(fd0)/boot/root.img.gz
	

We need to be root to do this part, so raise your hand to get root access to this section.

	mount -o loop /home/$USER/myboot/root.img \
	/home/$USER/myboot/mnt
	cp -a /home/$USER/myboot/rootfs/* \
	/home/$USER/myboot/mnt
	umount /home/$USER/myboot/mnt
	

Now we must compress this image so it will fit on the floppy disk with everything else.

	gzip -9 /home/$USER/myboot/root.img
	

Now we need to populate the floppy disk with the GRUB boot loader, we'll still need root priviledges to do this part.

	mke2fs /dev/fd0
	mount /dev/fd0 /home/$USER/myboot/mnt/
	
	mkdir /home/$USER/myboot/mnt/boot
	mkdir /home/$USER/myboot/mnt/boot/grub
	
	mount /boot
	cp -p /boot/grub/* /home/$USER/myboot/mnt/boot/grub
	 
	cp /home/$USER/myboot/linux-2.4.25/arch/i386/boot/bzImage \
	/home/$USER/myboot/mnt/boot
	
	cp /home/$USER/myboot/menu.lst \
	/home/$USER/myboot/mnt/boot/grub/menu.lst

	cp /home/$USER/myboot/menu.lst \
	/home/$USER/myboot/mnt/boot/grub/grub.conf
	
	cp /home/$USER/myboot/root.img.gz \
	/home/$USER/myboot/mnt/boot
	

Now we take our grubfd.conf file and install grub on the floppy disk using this command: grep -v ^# /home/$USER/myboot/grubfd.conf | grub --batch