#!/bin/bash # mkbootdisk # # Written by Erik Troan pause=yes unset kernel device=/dev/fd0 unset verbose unset kernelargs unset mountopts unset isoimage unset realdev size=1440 failed=0 MOUNTDIR=`mktemp -d /tmp/mkbootdisk.XXXXXX` PATH=/sbin:$PATH export PATH VERSION=1.5.3 usage () { cat >&2 <] [--verbose -v] [--iso] [--kernelargs ] [--size ] (ex: `basename $0` --device /dev/fd1 2.0.31) EOF exit $1 } while [ $# -gt 0 ]; do case $1 in --device) shift device=$1 ;; --kernelargs) shift kernelargs=$1 ;; --help) rm -rf $MOUNTDIR usage 0 ;; --iso) isoimage=1 ;; --size) shift size=$1 ;; --noprompt) unset pause ;; -v) verbose=true ;; --verbose) verbose=true ;; --version) echo "mkbootdisk: version $VERSION" rm -rf $MOUNTDIR exit 0 ;; *) if [ -z "$kernel" ]; then kernel=$1 else rm -rf $MOUNTDIR usage fi ;; esac shift done [ -z "$kernel" ] && { rm -rf $MOUNTDIR usage 1 } [ "$(uname -i)" == "x86_64" ] && [ -z $isoimage ] && { echo "Image for x86_64 architecture does not fit on 1.44MB floppy." >&2 echo "Use \"--iso --device image.iso\" options to make a CD image." >&2 exit 1 } [ -d /lib/modules/$kernel ] || { echo "/lib/modules/$kernel is not a directory." >&2 rm -rf $MOUNTDIR exit 1 } [ -f /boot/vmlinuz-$kernel ] || { echo "/boot/vmlinuz-$kernel does not exist." >&2 rm -rf $MOUNTDIR exit 1 } rootdev=`awk '$1 ~ /^[^#]/ && $2 ~ /^\/$/ { print $1 ; exit }' /etc/fstab` if [ $(echo $rootdev | cut -c1-6) = "LABEL=" ]; then rootlabel=$(echo $rootdev | cut -c7-) # whee, now we have to look through every partition looking for # the thing called $rootlabel, which could be raid. Ick. list=$(tail -n +3 /proc/partitions | awk '{ print $4 '} | grep '^md') list="$list $(tail -n +3 /proc/partitions | awk '{ print $4 '} | grep -v '^md')" rootdev="" for dev in $list; do if tune2fs -l /dev/$dev >/dev/null 2>/dev/null; then label=$(tune2fs -l /dev/$dev 2>/dev/null | grep "Filesystem volume name" | awk '{print $4}') if [ "$label" = $rootlabel ]; then rootdev=/dev/$dev break fi fi done fi if [ -z "$kernelargs" -a -x /sbin/grubby -a -f /boot/grub/grub.conf ]; then # sed gross... this grep's for the args= line and removes the args=" and "$ defkernel=$(grubby --default-kernel) if [ -n "$defkernel" ]; then kernelargs=$(grubby --info "$defkernel" | sed -n '/^args=/{s/^args="//;s/"$//;p;}') fi fi [ -z "$rootdev" ] && { echo 'Cannot find root partition in /etc/fstab.' >&2 rm -rf $MOUNTDIR exit 1 } rm -rf $MOUNTDIR mkdir $MOUNTDIR || { echo "Failed to create $MOUNTDIR" >&2 exit 1 } [ -d $MOUNTDIR ] || { echo "$MOUNTDIR is not a directory!" >&2 rm -rf $MOUNTDIR exit 1 } if [ -n "$isoimage" ]; then cfgfile=$MOUNTDIR/isolinux/isolinux.cfg bootmsg=$MOUNTDIR/isolinux/boot.msg # create an iso image; the directory is all we need [ -n "$verbose" ] && echo -n "Installing isolinux... " mkdir $MOUNTDIR/isolinux cp /usr/lib/syslinux/isolinux.bin $MOUNTDIR/isolinux [ -n "$verbose" ] && echo done else cfgfile=$MOUNTDIR/syslinux.cfg bootmsg=$MOUNTDIR/boot.msg # we need to create an msdos filesystem for syslinux if [ -b "$device" ]; then if [ -n "$pause" ]; then echo "Insert a disk in $device. Any information on the disk will be lost." echo -n "Press to continue or ^C to abort: " read aline fi # this is copying some bits from below. oh well realdev=$device device=`/bin/mktemp /tmp/mkbootdisk.XXXXXX` dd if=/dev/zero of=$device bs=1024 count=$size 2> /dev/null mountopts=loop elif [ -f "$device" ]; then echo "$device exists but is not a block device." rmdir $MOUNTDIR exit 1 else dd if=/dev/zero of=$device bs=1024 count=$size 2> /dev/null mountopts=loop fi [ -n "$verbose" ] && echo -n "Formatting $device... " mkdosfs -r 16 -I $device > /dev/null || { echo "Failed to format $device" >&2 rmdir $MOUNTDIR [ -n "$realdev" ] && rm -f "$device" exit 1 } syslinux $device [ -n "$verbose" ] && echo "done." mount -o "$mountopts" -t vfat $device $MOUNTDIR || { rmdir $MOUNTDIR [ -n "$realdev" ] && rm -f "$device" exit 1 } fi if [ -n "$isoimage" ]; then BOOTDESTDIR=$MOUNTDIR/isolinux else BOOTDESTDIR=$MOUNTDIR fi [ -n "$verbose" ] && echo -n "Copying /boot/vmlinuz-$kernel... " cp -p /boot/vmlinuz-$kernel $BOOTDESTDIR/vmlinuz [ $? = 0 ] || failed=1 [ -n "$verbose" ] && echo "done." [ -n "$verbose" ] && echo -n "Copying /boot/initrd-$kernel.img... " if [ -f /boot/initrd-$kernel.img ]; then cp -p /boot/initrd-$kernel.img $BOOTDESTDIR/initrd.img fi [ $? = 0 ] || failed=1 [ -n "$verbose" ] && echo "done." [ -n "$verbose" ] && echo -n "Configuring bootloader... " [ -f $BOOTDESTDIR/initrd.img ] && INITRDARG="initrd=initrd.img" if [ $(echo $rootdev | cut -b 6-9) = "loop" ]; then rootdev=$(ls -l $rootdev | sed 's/,//' | awk '{ printf("%02x%02x\n", $5, $6); }') fi cat > $cfgfile <> $bootmsg < (or wait 10 seconds) to boot your $title system from $rootdev. You may override the default linux kernel parameters by typing "linux ", followed by if you like. EOF [ $? = 0 ] || failed=1 [ -n "$verbose" ] && echo "done." if [ -n "$isoimage" ]; then mkisofs \ -A "Red Hat Linux Boot CD" \ -V "Red Hat Linux Boot CD" \ -J -R -T -quiet \ -o $device \ -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot \ -boot-load-size 4 -boot-info-table $MOUNTDIR rm -rf $MOUNTDIR else umount $MOUNTDIR rmdir $MOUNTDIR fi if [ -n "$realdev" ] && [ $failed -eq 0 ]; then dd if="$device" of="$realdev" bs=72k rm -f "$device" fi if [ $failed -eq 1 ]; then exit 1 else exit 0 fi