diff --git a/examples/bootfloppy/bootfloppy.txt b/examples/bootfloppy/bootfloppy.txt new file mode 100644 index 000000000..575c93fcc --- /dev/null +++ b/examples/bootfloppy/bootfloppy.txt @@ -0,0 +1,185 @@ +Building a Busybox Boot Floppy +============================== + +This document describes how to buid a boot floppy using the following +components: + + - Linux Kernel (http://www.kernel.org) + - uClibc: C library (http://cvs.uclinux.org/uClibc.html) + - Busybox: Unix utilities (http://busybox.lineo.com) + - Syslinux: bootloader (http://syslinux.zytor.com) + +It is based heavily on a paper presented by Erik Andersen at the 2001 Embedded +Systems Conference. + + + +Building The Software Components +-------------------------------- + +Detailed instructions on how to build Busybox, uClibc, or a working Linux +kernel are beyond the scope of this document. The following guidelines will +help though: + + - Stock Busybox from CVS or a tarball will work with no modifications to + any files. Just extract and go. + - Ditto uClibc. + - Your Linux kernel must include support for initrd or else the floppy + won't be able to mount it's root file system. + +If you require further information on building Busybox uClibc or Linux, please +refer to the web pages and documentation for those individual programs. + + + +Making a Root File System +------------------------- + +The following steps will create a root file system. + + - Create an empty file that you can format as a filesystem: + + dd if=/dev/zero of=rootfs bs=1k count=4000 + + - Set up the rootfs file we just created to be used as a loop device (may not + be necessary) + + losetup /dev/loop0 rootfs + + - Format the rootfs file with a filesystem: + + mkfs.ext2 -F -i 2000 rootfs + + - Mount the file on a mountpoint so we can place files in it: + + mkdir loop + mount -o loop rootfs loop/ + + (you will probably need to be root to do this) + + - Copy on the C library, the dynamic linking library, and other necessary + libraries. For this example, we copy the following files from the uClibc + tree: + + mkdir loop/lib + (chdir to uClibc directory) + cp -a libc.so* uClibc*.so \ + ld.so-1/d-link/ld-linux-uclibc.so* \ + ld.so-1/libdl/libdl.so* \ + crypt/libcrypt.so* \ + (path to)loop/lib + + - Install the Busybox binary and accompanying symlinks: + + (chdir to busybox directory) + make PREFIX=(path to)loop/ install + + - Make device files in /dev: + + This can be done by running the 'mkdevs.sh' script. If you want the gory + details, you can read the script. + + - Make necessary files in /etc: + + For this, just cp -a the etc/ directory onto rootfs. Again, if you want + all the details, you can just look at the files in the dir. + + - Run ldconfig so busybox and other binaries can have access to the libraries + that they need: + + (path to)uClibc/ld.so-1/util/ldconfig -r loop/ + + - Unmount the rootfs from the mountpoint: + + umount loop + + - Compress it: + + gzip -9 rootfs + + +Making a SYSLINUX boot floppy +----------------------------- + +The following steps will create the boot floppy. + +Note: You will need to have the mtools package installed beforehand. + + - Insert a floppy in the drive and format it with an MSDOS filesystem: + + mformat a: + + (if the system doesn't know what device 'a:' is, look at /etc/mtools.conf) + + - Run syslinux on the floppy: + + syslinux -s /dev/fd0 + + (the -s stands for "safe, slow, and stupid" and should work better with + buggy BIOSes; it can be omitted) + + - Put on a syslinux.cfg file: + + mcopy syslinux.cfg a: + + (more on syslinux.cfg below) + + - Copy the root file system you made onto the MSDOS formatted floppy + + mcopy rootfs.gz a: + + - Build a linux kernel and copy it onto the disk with the filename 'linux' + + mcopy bzImage a:linux + + +Sample syslinux.cfg +~~~~~~~~~~~~~~~~~~~ + +The following simple syslinux.cfg file should work. You can tweak it if you +like. + +----begin-syslinux.cfg--------------- +DEFAULT linux +APPEND initrd=rootfs.gz root=/dev/ram0 +TIMEOUT 10 +PROMPT 1 +----end-syslinux.cfg--------------- + +Some changes you could make to syslinux.cfg: + + - This value is the number seconds it will wait before booting. You can set + the timeout to 0 (or omit) to boot instantly, or you can set it as high as + 10 to wait awhile. + + - PROMPT can be set to 0 to disable the 'boot:' prompt. + + - you can add this line to display the contents of a file as a welcome + message: + + DISPLAY display.txt + + + +Additional Resources +-------------------- + +Other useful information on making a Linux bootfloppy is available at the +following URLs: + +http://www.linuxdoc.org/HOWTO/Bootdisk-HOWTO/index.html +http://www.linux-embedded.com/howto/Embedded-Linux-Howto.html +http://linux-embedded.org/howto/LFS-HOWTO.html +http://linux-embedded.org/pmhowto.html +http://recycle.lbl.gov/~ldoolitt/embedded/ (Larry Doolittle's stuff) + + + +Possible TODOs +-------------- + +The following features that we might want to add later: + + - support for additional filesystems besides ext2, i.e. minix + - different libc, static vs dynamic loading + - maybe using an alternate bootloader diff --git a/examples/bootfloppy/display.txt b/examples/bootfloppy/display.txt new file mode 100644 index 000000000..399d326d9 --- /dev/null +++ b/examples/bootfloppy/display.txt @@ -0,0 +1,4 @@ + +This boot floppy is made with Busybox, uClibc, and the Linux kernel. +Hit RETURN to boot or enter boot parameters at the prompt below. + diff --git a/examples/bootfloppy/etc/fstab b/examples/bootfloppy/etc/fstab new file mode 100644 index 000000000..ef14ca2cc --- /dev/null +++ b/examples/bootfloppy/etc/fstab @@ -0,0 +1,2 @@ +proc /proc proc defaults 0 0 + diff --git a/examples/bootfloppy/etc/init.d/rcS b/examples/bootfloppy/etc/init.d/rcS new file mode 100755 index 000000000..4f29b923f --- /dev/null +++ b/examples/bootfloppy/etc/init.d/rcS @@ -0,0 +1,3 @@ +#! /bin/sh + +/bin/mount -a diff --git a/examples/bootfloppy/etc/inittab b/examples/bootfloppy/etc/inittab new file mode 100644 index 000000000..eb3e979ce --- /dev/null +++ b/examples/bootfloppy/etc/inittab @@ -0,0 +1,5 @@ +::sysinit:/etc/init.d/rcS +::respawn:-/bin/sh +tty2::askfirst:-/bin/sh +::ctrlaltdel:/bin/umount -a -r + diff --git a/examples/bootfloppy/etc/profile b/examples/bootfloppy/etc/profile new file mode 100644 index 000000000..e9b11e90a --- /dev/null +++ b/examples/bootfloppy/etc/profile @@ -0,0 +1,8 @@ +# /etc/profile: system-wide .profile file for the Bourne shells + +echo +echo -n "Processing /etc/profile... " +# no-op +echo "Done" +echo + diff --git a/examples/bootfloppy/mkdevs.sh b/examples/bootfloppy/mkdevs.sh new file mode 100755 index 000000000..03a1a8550 --- /dev/null +++ b/examples/bootfloppy/mkdevs.sh @@ -0,0 +1,62 @@ +#!/bin/sh +# +# makedev.sh - creates device files for a busybox boot floppy image + + +# we do our work in the dev/ directory +if [ -z "$1" ]; then + echo "usage: `basename $0` path/to/dev/dir" + exit 1 +fi + +cd $1 + + +# miscellaneous one-of-a-kind stuff +mknod console c 5 1 +mknod full c 1 7 +mknod kmem c 1 2 +mknod mem c 1 1 +mknod null c 1 3 +mknod port c 1 4 +mknod random c 1 8 +mknod urandom c 1 9 +mknod zero c 1 5 +ln -s /proc/kcore core + +# IDE HD devs +# note: not going to bother creating all concievable partitions; you can do +# that yourself as you need 'em. +mknod hda b 3 0 +mknod hdb b 3 64 +mknod hdc b 22 0 +mknod hdd b 22 64 + +# loop devs +for i in `seq 0 7`; do + mknod loop$i b 7 $i +done + +# ram devs +for i in `seq 0 9`; do + mknod ram$i b 1 $i +done +ln -s ram1 ram + +# ttys +mknod tty c 5 0 +for i in `seq 0 9`; do + mknod tty$i c 4 $i +done + +# virtual console screen devs +for i in `seq 0 9`; do + mknod vcs$i b 7 $i +done +ln -s vcs0 vcs + +# virtual console screen w/ attributes devs +for i in `seq 0 9`; do + mknod vcsa$i b 7 $i +done +ln -s vcsa0 vcsa diff --git a/examples/bootfloppy/mkrootfs.sh b/examples/bootfloppy/mkrootfs.sh new file mode 100755 index 000000000..cd6bef632 --- /dev/null +++ b/examples/bootfloppy/mkrootfs.sh @@ -0,0 +1,106 @@ +#!/bin/bash +# +# mkrootfs.sh - creates a root file system +# + +# TODO: need to add checks here to verify that busybox, uClibc and bzImage +# exist + + +# command-line settable variables +BUSYBOX_DIR=.. +UCLIBC_DIR=../../uClibc +TARGET_DIR=./loop +FSSIZE=4000 +CLEANUP=1 +MKFS='mkfs.ext2 -F' + +# don't-touch variables +BASE_DIR=`pwd` + + +while getopts 'b:u:s:t:Cm' opt +do + case $opt in + b) BUSYBOX_DIR=$OPTARG ;; + u) UCLIBC_DIR=$OPTARG ;; + t) TARGET_DIR=$OPTARG ;; + s) FSSIZE=$OPTARG ;; + C) CLEANUP=0 ;; + m) MKFS='mkfs.minix' ;; + *) + echo "usage: `basename $0` [-bu]" + echo " -b DIR path to busybox direcory (default ..)" + echo " -u DIR path to uClibc direcory (default ../../uClibc)" + echo " -t DIR path to target direcory (default ./loop)" + echo " -s SIZE size of root filesystem in Kbytes (default 4000)" + echo " -C don't perform cleanup (umount target dir, gzip rootfs, etc.)" + echo " (this allows you to 'chroot loop/ /bin/sh' to test it)" + echo " -m use minix filesystem (default is ext2)" + exit 1 + ;; + esac +done + + + + +# clean up from any previous work +mount | grep -q loop +[ $? -eq 0 ] && umount $TARGET_DIR +[ -d $TARGET_DIR ] && rm -rf $TARGET_DIR/ +[ -f rootfs ] && rm -f rootfs +[ -f rootfs.gz ] && rm -f rootfs.gz + + +# prepare root file system and mount as loopback +dd if=/dev/zero of=rootfs bs=1k count=$FSSIZE +$MKFS -i 2000 rootfs +mkdir $TARGET_DIR +mount -o loop,exec rootfs $TARGET_DIR # must be root + + +# install uClibc +mkdir -p $TARGET_DIR/lib +cd $UCLIBC_DIR +make INSTALL_DIR= +cp -a libc.so* $BASE_DIR/$TARGET_DIR/lib +cp -a uClibc*.so $BASE_DIR/$TARGET_DIR/lib +cp -a ld.so-1/d-link/ld-linux-uclibc.so* $BASE_DIR/$TARGET_DIR/lib +cp -a ld.so-1/libdl/libdl.so* $BASE_DIR/$TARGET_DIR/lib +cp -a crypt/libcrypt.so* $BASE_DIR/$TARGET_DIR/lib +cd $BASE_DIR + + +# install busybox and components +cd $BUSYBOX_DIR +make distclean +make CC=$BASE_DIR/$UCLIBC_DIR/extra/gcc-uClibc/i386-uclibc-gcc +make PREFIX=bootfloppy/loop install +cd $BASE_DIR + + +# make files in /dev +mkdir $TARGET_DIR/dev +./mkdevs.sh $TARGET_DIR/dev + + +# make files in /etc +cp -a etc $TARGET_DIR +ln -s /proc/mounts $TARGET_DIR/etc/mtab + + +# other miscellaneous setup +mkdir $TARGET_DIR/initrd +mkdir $TARGET_DIR/proc +$UCLIBC_DIR/ld.so-1/util/ldconfig -r $TARGET_DIR + + +# Done. Maybe do cleanup. +if [ $CLEANUP -eq 1 ] +then + umount $TARGET_DIR + rmdir $TARGET_DIR + gzip -9 rootfs +fi + diff --git a/examples/bootfloppy/mksyslinux.sh b/examples/bootfloppy/mksyslinux.sh new file mode 100755 index 000000000..e25417353 --- /dev/null +++ b/examples/bootfloppy/mksyslinux.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# +# Formats a floppy to use Syslinux + +dummy="" + + +# need to have mtools installed +if [ -z `which mformat` -o -z `which mcopy` ]; then + echo "You must have the mtools package installed to run this script" + exit 1 +fi + + +# need an arg for the location of the kernel +if [ -z "$1" ]; then + echo "usage: `basename $0` path/to/linux/kernel" + exit 1 +fi + + +# need to have a root file system built +if [ ! -f rootfs.gz ]; then + echo "You need to have a rootfs built first." + echo "Hit RETURN to make one now or Control-C to quit." + read dummy + ./mkrootfs.sh +fi + + +# prepare the floppy +echo "Please insert a blank floppy in the drive and press RETURN to format" +echo "(WARNING: All data will be erased! Hit Control-C to abort)" +read dummy + +echo "Formatting the floppy..." +mformat a: +echo "Making it bootable with Syslinux..." +syslinux -s /dev/fd0 +echo "Copying Syslinux configuration files..." +mcopy syslinux.cfg display.txt a: +echo "Copying root filesystem file..." +mcopy rootfs.gz a: +# XXX: maybe check for "no space on device" errors here +echo "Copying linux kernel..." +mcopy $1 a:linux +# XXX: maybe check for "no space on device" errors here too +echo "Finished: boot floppy created" diff --git a/examples/bootfloppy/quickstart.txt b/examples/bootfloppy/quickstart.txt new file mode 100644 index 000000000..0d8090824 --- /dev/null +++ b/examples/bootfloppy/quickstart.txt @@ -0,0 +1,15 @@ +Quickstart on making the Busybox boot-floppy: + + 1) Download Busybox and uClibc from CVS or tarballs. Make sure they share a + common parent directory. (i.e. busybox/ and uclibc/ are both right off of + /tmp, or wherever.) + + 2) Build a Linux kernel. Make sure you include support for initrd. + + 3) Put a floppy in the drive. Make sure it is a floppy you don't care about + because the contents will be overwritten. + + 4) As root, type ./mksyslinux.sh path/to/linux/kernel from this directory. + Wait patiently while the magic happens. + + 5) Boot up on the floppy. diff --git a/examples/bootfloppy/syslinux.cfg b/examples/bootfloppy/syslinux.cfg new file mode 100644 index 000000000..8d407cad4 --- /dev/null +++ b/examples/bootfloppy/syslinux.cfg @@ -0,0 +1,7 @@ +display display.txt +default linux +timeout 10 +prompt 1 +label linux + kernel linux + append initrd=rootfs.gz root=/dev/ram0