#!/bin/sh # $Id: create_slackboots.sh,v 1.9 2006/10/01 11:01:57 root Exp root $ # ---------------------------------------------------------------------- # Purpose: # 1) Create initrd.img and pxelinux.cfg/default for PXE boot; # 2) Create a bootable USB image for the Slackware installer. # Needed: # The 'isolinux' and 'kernels' directories from the Slackware tree. # Author: # Eric Hameleers 07-sep-2006 # ---------------------------------------------------------------------- STAGING=${STAGING:-/tmp/slackboot} SLACKROOT=${SLACKROOT:-/home/ftp/pub/Linux/Slackware/slackware-current} INITRD="${SLACKROOT}/isolinux/initrd.img" NETWORK="${SLACKROOT}/isolinux/network.dsk" NETWORK26="${SLACKROOT}/isolinux/network26.dsk" PCMCIA="${SLACKROOT}/isolinux/pcmcia.dsk" PXECFG="${SLACKROOT}/isolinux/isolinux.cfg" DEFKERNEL="sata.i" SYSMAP="${SLACKROOT}/kernels/${DEFKERNEL}/System.map.gz" SYSMAP26="${SLACKROOT}/kernels/huge26.s/System.map.gz" CWD=$( pwd ) SRCDIR=$( dirname $0 ) [ "${SRCDIR:0:1}" == "." ] && SRCDIR=${CWD}/${SRCDIR} # ---------------------------------------------------------------------- # Do not tolerate sloppy scripting: set -u set -e trap 'echo "*** $0 FAILED ***"' ERR OPTION=${1:-""} # Cleanup function (removes tempfiles, unmount loopmounted images) cleanup() { # Clean up: echo "--- Unmounting image files and deleting temporaries: ---" set +e umount ${STAGING}/in umount ${STAGING}/network umount ${STAGING}/network26 umount ${STAGING}/pcmcia umount ${STAGING}/out umount ${STAGING}/usb rm -f ${STAGING}/initrd.dsk rm -f ${STAGING}/newinitrd rm -f ${STAGING}/System.map set -e } # Reset to a clean environment: cleanup 2>/dev/null # Delete any existing output files from a previous run: rm -f ${STAGING}/{initrd.img*,usbboot.img*} rm -f ${STAGING}/pxelinux.cfg_default if [ "$OPTION" == "-c" ]; then # "-c" means "cleanup, do nothing more. exit 0 fi if [ ! -d $SLACKROOT ]; then echo "*** I can't find the Slackware package tree $SLACKROOT!" exit 1 fi # STAGING is where we will do all our work: # loop-mounting the images, transfering data, writing the resulting images. [ ! -d ${STAGING} ] && ( mkdir -p $STAGING || ( echo "*** Could not create directory ${STAGING}!"; exit 1 ) ) # Mount points: mkdir ${STAGING}/{in,network,network26,pcmcia,out,usb} 2>/dev/null || true # OK... work starts here: # # PXE initrd.img and pxelinux.cfg/default files: # # Expand the gzipped root fs and the System.map: gunzip -cd ${INITRD} > ${STAGING}/initrd.dsk gunzip -cd ${SYSMAP} > ${STAGING}/System.map gunzip -cd ${SYSMAP26} > ${STAGING}/System26.map # Calculate sizes: let IMGSIZE=$( du -sk ${STAGING}/initrd.dsk | cut -f1 ) let IMGSIZE=IMGSIZE+$( du -sk ${NETWORK} | cut -f1 ) let IMGSIZE=IMGSIZE+$( du -sk ${NETWORK26} | cut -f1 ) let IMGSIZE=IMGSIZE+$( du -sk ${PCMCIA} | cut -f1 ) # Create new image file big enough to contain the resulting initrd: echo "--- Creating disk image file for 'initrd.img': ---" dd if=/dev/zero of=${STAGING}/newinitrd bs=1k count=$IMGSIZE # Create an ext2 filesystem in it: echo "--- Formatting disk image file with ext2: ---" mkfs.ext2 -m 0 -F ${STAGING}/newinitrd tune2fs -i 0 ${STAGING}/newinitrd # Mount images and start copying data: mount -o loop ${STAGING}/newinitrd ${STAGING}/out/ mount -o loop,ro ${STAGING}/initrd.dsk ${STAGING}/in/ mount -o loop,ro ${NETWORK} ${STAGING}/network/ mount -o loop,ro ${NETWORK26} ${STAGING}/network26/ mount -o loop,ro ${PCMCIA} ${STAGING}/pcmcia/ echo "--- Copying data to loop-mounted disk image file: ---" KVER=$( basename $( ls ${STAGING}/network/lib/modules/ ) ) KVER26=$( basename $( ls ${STAGING}/network26/lib/modules/ ) ) echo -n " >>> Slackware initrd.img " cp -a ${STAGING}/in/* ${STAGING}/out/ echo -n "network.dsk " cp -a ${STAGING}/network/* ${STAGING}/out/ echo -n "network26.dsk " cp -a ${STAGING}/network26/* ${STAGING}/out/ echo -n "pcmcia.dsk " cp -a ${STAGING}/pcmcia/* ${STAGING}/out/ echo "<<<" # Re-generate the module dependency files: rm -f ${STAGING}/out/lib/modules/${KVER}/modules.* /sbin/depmod -a -b ${STAGING}/out -F ${STAGING}/System.map $KVER rm -f ${STAGING}/out/lib/modules/${KVER26}/modules.* /sbin/depmod -a -b ${STAGING}/out -F ${STAGING}/System26.map $KVER26 # Copying/patching pcmcia and network scripts: cat $SRCDIR/pcmcia > ${STAGING}/out/bin/pcmcia cat $SRCDIR/network > ${STAGING}/out/bin/network patch -p0 ${STAGING}/out/scripts/network.sh $SRCDIR/network.sh.diff # Generate a pxelinux.cfg/default file cat ${PXECFG} |sed -e "s/ramdisk_size=[[:digit:]]*/ramdisk_size=${IMGSIZE}/" \ -e "s#/kernels/#kernels/#" \ > ${STAGING}/pxelinux.cfg_default # Gzip the new initrd (we umount and remount it for this purpose): umount ${STAGING}/out echo "--- Gzipping the resulting initrd image: ---" gzip -9cf ${STAGING}/newinitrd > ${STAGING}/initrd.img (cd ${STAGING} && md5sum initrd.img > initrd.img.md5) mount -o loop ${STAGING}/newinitrd ${STAGING}/out/ echo "" echo "------------------------------------------------------------------------" echo "The new combined initrd.img file (for PXE and USB boot) is:" echo " '${STAGING}/initrd.img'" echo "The accompanying pxelinux.cfg/default file is:" echo " '${STAGING}/pxelinux.cfg_default'" echo "------------------------------------------------------------------------" echo "" # # --- The usbboot.img file --- # # Calculate sizes: let USBIMG=$( du -sk ${STAGING}/initrd.img | cut -f1 ) for KERN in ${SLACKROOT}/kernels/*.?/*zImage ; do let USBIMG=USBIMG+$(du -sk $KERN | cut -f1 ) done let USBIMG=USBIMG+512 # Add just that little extra.. # Create a DOS formatted image file echo "--- Creating an image for the USB boot disk: ---" mkfs.msdos -n USBSLACK -F 16 -C ${STAGING}/usbboot.img $USBIMG file ${STAGING}/usbboot.img # Copy all relevant files into the image. # Use the PXE boot initrd.img and pxelinux.cfg files so that we don't need # to add separate network.dsk and pcmcia.dsk images: mount -o loop,rw ${STAGING}/usbboot.img ${STAGING}/usb echo "--- Copying data to the USB boot disk image: ---" cp $SLACKROOT/isolinux/isolinux.bin ${STAGING}/usb cp $SLACKROOT/isolinux/setpkg ${STAGING}/usb/ cp $SLACKROOT/isolinux/{f*.txt,message.txt} ${STAGING}/usb/ cp ${STAGING}/initrd.img ${STAGING}/usb/ cat ${STAGING}/pxelinux.cfg_default |sed -e 's# kernels/# #g' -e 's#/.zImage##' > ${STAGING}/usb/syslinux.cfg # Syslinux can not cope with subdirectories: echo "--- Making the image bootable: ---" ( cd $SLACKROOT/kernels/ for dir in `find -type d -name "*.?" -maxdepth 1` ; do cp $dir/*zImage ${STAGING}/usb/$dir ; done ) sync # Stamp the file with the syslinux bootloader: # > Do "vi ~/.mtoolsrc" to add "mtools_skip_check=1", # > if the next command gives an error: umount ${STAGING}/usb syslinux -s ${STAGING}/usbboot.img (cd ${STAGING} && md5sum usbboot.img > usbboot.img.md5) mount -o loop,rw ${STAGING}/usbboot.img ${STAGING}/usb echo "" echo "------------------------------------------------------------------------" echo "The new usbboot.img file (for USB boot) is:" echo " '${STAGING}/usbboot.img'" echo "------------------------------------------------------------------------" echo "" # Pass the "-n" option to prevent cleanup and umounts from happening # (useful for forensic inspection :-) if [ "$OPTION" == "-n" ]; then echo "*** NOT unmounting the loop-mounted images." echo "*** You can inspect their content below the mountpoints in '${STAGING}'" exit else # File removal/umounts cleanup fi