#!/bin/bash # Vadim Berkgaut 2003 GPL # This script creates root filesystem (together with the kernel) ready # to be installed on Compact Flash card or Disk-on-Module. The resulting # mini-distribution will boot from flash and run from tmpfs in memory. # Otherwise it is not different from Debian and can be upgraded from # debian archives. It is intended for diskless Linux routers. # The script requires wget and debootstrap to run. You also need to # prepare statically linked busybox binary (with mount, umount, cp, # pivot_root, freeramdisk and sh). The kernel on the source system # should support loop devices. Tested with debootstrap 0.1.17. ################# Configurable parameters ############################ # debian distribution DIST=woody # create directory tree under ./debian-router ROOT=$PWD/debian-router # set to your fastest mirror DEBIAN_ARCHIVE=http://ftp.de.debian.org/debian/ # final destinations for /boot and / on flash; better # do not touch, or read the script through first FLASH_BOOT_DEV=/dev/hda1 FLASH_ROOT_DEV=/dev/hda2 # should be less than the size of the flash TMPFS_SIZE=100m # uncomment if you don't need documentation (saves about 10MB): # JUNK="/usr/share/locale /usr/share/doc /usr/share/man /usr/share/info \ # /usr/doc /usr/lib/gconv" # or uncomment if you do: JUNK="/usr/share/locale" # Statically linked busybox binary, needed for initrd. It should support # mount, umount, cp, pivot_root, freeramdisk and shell (tested with msh). BUSYBOX=/home/berk/tmp/busybox ################### Main part: debootstrap ############################# test -f $BUSYBOX || { echo "busybox not found"; exit 1; } test -d $ROOT || mkdir $ROOT cd $ROOT/.. debootstrap --exclude=\ base-config,console-data,console-tools,console-tools-libs,\ console-common,exim,libident,libldap2,libpcre3,libsasl7,\ modconf,manpages,man-db,groff-base,info,syslinux,ipchains,\ pppoeconf,pppoe,pppconfig,ppp,pciutils,fdutils,bsdmainutils,tasksel,\ gettext-base,pcmcia-cs,at,logrotate,mailx,libgdbmg1 \ $DIST $ROOT $DEBIAN_ARCHIVE ################ Get newer packages and the kernel #################### echo echo "Upgrading the system and adding new packages" export DEBIAN_FRONTEND=noninteractive >$ROOT/etc/apt/sources.list cat <$ROOT/etc/hosts cat <$ROOT/etc/kernel-img.conf cat <$ROOT/etc/apt/apt.conf cat <<'EOF' Dir "/" { // Do without apt binary caches to save space Cache "var/cache/apt/" { archives "archives/"; srcpkgcache ""; pkgcache ""; }; }; DPkg { Post-Invoke {"/usr/local/sbin/cleanup";}; } EOF >$ROOT/etc/fstab cat <<'EOF' # /etc/fstab: static file system information. # # tmpfs / tmpfs rw 0 0 proc /proc proc defaults 0 0 EOF >$ROOT/etc/lilo.conf cat <<'EOF' # you can use 'lba32' with newer BIOSes geometric boot=/dev/hda root=/dev/ram0 install=/boot/boot-menu.b map=/boot/map delay=20 prompt timeout=20 vga=normal append="hda=flash" image=/boot/vmlinuz label=linux read-write initrd=/boot/initrd optional image=/boot/vmlinuz.old label=linuxold read-write initrd=/boot/initrd optional image=/boot/vmlinuz.backup label=backup read-write initrd=/boot/initrd EOF >$ROOT/etc/kernel-img.conf cat <<'EOF' link_in_boot = yes do_boot_enable = yes do_bootfloppy = no do_bootloader = no silent_loader = yes preinst_hook = /usr/local/sbin/mountboot postinst_hook = /usr/local/sbin/run_lilo prerm_hook = /usr/local/sbin/mountboot postrm_hook = /usr/local/sbin/run_lilo EOF ######################## Prepare initrd ############################ echo echo "Preparing initrd" cd $ROOT/initrd mkdir bin dev initrd mnt proc sbin cp $BUSYBOX bin/busybox >sbin/init cat </dev/console 2>&1 EOF >bin/detect cat <<'EOF' #!/bin/sh umount /initrd /tmp/busybox freeramdisk /dev/ram0 && echo "freeramdisk ok" find /lib/modules/* -maxdepth 0 -type d ! -name `uname -r` | xargs rm -rf rm /tmp/busybox /etc/mtab ln -s /proc/mounts /etc/mtab echo Detecting PCI cards... cut -b 1-42 /lib/modules/`uname -r`/modules.pcimap | \ sed "s/ 0x0000//g" | fgrep "`cut -f 2 /proc/bus/pci/devices`" | \ cut -d ' ' -f 1 | sort | xargs -l1 /sbin/modprobe test -f /sbin/init || exec /bin/sh exec /sbin/init EOF chmod 755 bin/busybox bin/detect sbin/init cd $ROOT/dev cp -a console hda hda[1-4] $ROOT/initrd/dev IMAGE=$ROOT/boot/initrd test -f $IMAGE && rm $IMAGE dd if=/dev/zero of=$IMAGE bs=1k count=1024 mke2fs -F -m0 $IMAGE mount -t ext2 -o loop $IMAGE /mnt rmdir /mnt/lost+found cp -a $ROOT/initrd/* /mnt rm -rf $ROOT/initrd/* umount /mnt gzip -9 $IMAGE mv $IMAGE.gz $IMAGE echo "initrd done" ######### Scripts in /usr/local/sbin for system maintenance ########## cd $ROOT/usr/local/sbin >cleanup cat < 2003 # Removes parts of packages we can live without and cleans apt cache. # Invoked by APT:DPkg:Post-Invoke. dpkg --clear-avail for J in $JUNK ; do rm -rf \$J/* done rm -rf /var/cache/apt/archives/*.deb if [ -f /proc/mounts ] ; then for MOUNT in /boot /lib/modules /mnt ; do grep -q "\$MOUNT" /proc/mounts && umount \$MOUNT done fi echo "Cleaned up" EOF >mountboot cat < 2003 # Mounts /boot and /lib/modules from flash when we install a new kernel. umount_all() { for MOUNT in /boot /lib/modules /mnt ; do grep -q "\$MOUNT" /proc/mounts && umount \$MOUNT test -d \$MOUNT || mkdir \$MOUNT done } cd /; umount_all if mount $FLASH_ROOT_DEV /mnt -o noatime,rw && \\ mount $FLASH_BOOT_DEV /boot -o noatime,rw && \\ mount /mnt/lib/modules /lib/modules --bind && \\ umount /mnt then exit 0 else umount_all exit 1 fi EOF >run_lilo cat <wr cat < 2003 # Dumps changes in tmpfs to flash, Cisco style. Uses rsync # to avoid excessive writing to flash. while true ; do case "\$1" in a|-a|all|-all|--all) WRITE_ALL='y';; v|-v|verbose|-verbose|--verbose) WRITE_VERBOSE='v';; av|va|-av|-va) WRITE_ALL='y' ; WRITE_VERBOSE='v';; '') cd / ; break;; *) echo "Usage: wr [a|all] [v|verbose]" ; exit 1;; esac shift done RSYNC="/usr/bin/rsync" test -f \$RSYNC || exit 1 RSYNC="\$RSYNC -ax\$WRITE_VERBOSE --delete --temp-dir=/tmp" mount -t ext2 -o noatime $FLASH_ROOT_DEV /mnt || exit 1 \$RSYNC --exclude="/etc/fstab" --exclude="/etc/motd" \\ --exclude="/etc/ioctl.save" --exclude="/etc/mtab" \\ --exclude="/etc/network/ifstate" \\ /etc /mnt for FILE in /root/.profile /root/.bashrc /root/.mc/ini ; do DIR=\`dirname /mnt\$FILE\` test -e \$FILE && { test -d \$DIR || mkdir \$DIR; } && \\ \$RSYNC \$FILE /mnt\$FILE || rm -f /mnt\$FILE done echo "config saved" if [ \$WRITE_ALL ] ; then \$RSYNC \\ $EXCLUDE \\ /bin /lib /sbin /usr /mnt \$RSYNC --exclude="available*" \\ /var/lib/dpkg /var/lib/apt /mnt/var/lib echo "system saved" fi umount /mnt EOF chmod 700 cleanup mountboot wr run_lilo ######### Cleanup and prepare for installation to flash ################### chroot $ROOT /usr/local/sbin/cleanup rmdir $ROOT/floppy $ROOT/cdrom cd $ROOT/usr/share/mc rm -rf mc.hlp.* mc.hint.* cd $ROOT/.. >lilo.router.conf cat <<'EOF' disk=/dev/hdc bios=0x80 # you can use 'lba32' with newer BIOSes geometric boot=/dev/hdc delay=20 prompt timeout=20 vga=normal optional append="hda=flash" image=/boot/vmlinuz.backup label=backup root=/dev/ram0 read-write initrd=/boot/initrd EOF >debrouter_install cat <