summaryrefslogtreecommitdiffstats
path: root/usb-and-pxe-installers/usbimg2disk.sh
diff options
context:
space:
mode:
Diffstat (limited to 'usb-and-pxe-installers/usbimg2disk.sh')
-rw-r--r--usb-and-pxe-installers/usbimg2disk.sh278
1 files changed, 278 insertions, 0 deletions
diff --git a/usb-and-pxe-installers/usbimg2disk.sh b/usb-and-pxe-installers/usbimg2disk.sh
new file mode 100644
index 000000000..d98e21de4
--- /dev/null
+++ b/usb-and-pxe-installers/usbimg2disk.sh
@@ -0,0 +1,278 @@
+#!/bin/sh
+# $Id: usbimg2disk.sh,v 1.2 2009/05/14 10:29:38 eha Exp eha $
+#
+# Copyright 2009 Eric Hameleers, Eindhoven, NL
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Paranoid as usual:
+set -e
+
+showhelp() {
+ echo "# "
+ echo "# Purpose: to use the content of Slackware's usbboot.img and transform"
+ echo "# a standard USB thumb drive with a single vfat partition"
+ echo "# into an alternative USB boot device for the Slackware installer."
+ echo "# "
+ echo "# Reason: some computers refuse to boot from a USB thumb drive if it was"
+ echo "# made bootable by dumping 'usbboot.img' onto it."
+ echo "# "
+ echo "# Your USB thumb drive may contain data!"
+ echo "# This data will *not* be overwritten, unless you have"
+ echo "# explicitly chosen to format the drive by using the '-f' parameter."
+ echo "# "
+ echo "# $(basename $0) accepts the following parameters:"
+ echo "# -h|--help This help"
+ echo "# -f|--format Format the USB drive before use"
+ echo "# -i|--infile <filename> Full path to the usbboot.img file"
+ echo "# -l|--logfile <filename> Optional logfile to catch fdisk output"
+ echo "# -o|--outdev <filename> The device name of your USB drive"
+ echo "# -u|--unattended Do not ask any questions"
+ echo "# "
+ echo "# Example:"
+ echo "# "
+ echo "# $(basename $0) -i ~/download/usbboot.img -o /dev/sdX"
+ echo "# "
+}
+
+reformat() {
+ # Commands to re-create a functional USB stick with VFAT partition:
+ # Only parameter: the name of the USB device to be formatted:
+ TOWIPE="$1"
+
+ # Sanity checks:
+ if [ ! -b $TOWIPE ]; then
+ echo "*** Not a block device: '$TOWIPE' !"
+ exit 1
+ fi
+
+ # Wipe the MBR:
+ dd if=/dev/zero of=$TOWIPE bs=512 count=1
+
+ # create a FAT32 partition (type 'b')
+ /sbin/fdisk $TOWIPE <<EOF
+n
+p
+1
+
+
+t
+b
+w
+EOF
+
+ # Format with a vfat filesystem:
+ /sbin/mkdosfs -F32 ${TOWIPE}1
+}
+
+makebootable() {
+ # Only parameter: the name of the USB device to be set bootable:
+ USBDRV="$1"
+
+ # Sanity checks:
+ if [ ! -b $USBDRV ]; then
+ echo "Not a block device: '$USBDRV' !"
+ exit 1
+ fi
+
+ # Set the bootable flag for the first (and only...) partition:
+ /sbin/sfdisk $USBDRV -N1 <<EOF
+,,,*
+EOF
+}
+
+# Parse the commandline parameters:
+if [ -z "$1" ]; then
+ showhelp
+ exit 1
+fi
+while [ ! -z "$1" ]; do
+ case $1 in
+ -f|--format)
+ REFORMAT=1
+ shift
+ ;;
+ -h|--help)
+ showhelp
+ exit
+ ;;
+ -i|--infile)
+ USBIMG="$(cd $(dirname $2); pwd)/$(basename $2)"
+ shift 2
+ ;;
+ -l|--logfile)
+ LOGFILE="$(cd $(dirname $2); pwd)/$(basename $2)"
+ shift 2
+ ;;
+ -o|--outdev)
+ TARGET="$2"
+ TARGETPART="${TARGET}1"
+ shift 2
+ ;;
+ -u|--unattended)
+ UNATTENDED=1
+ shift
+ ;;
+ *)
+ echo "Unknown parameter '$1'!"
+ exit 1
+ ;;
+ esac
+done
+
+# Before we start:
+[ -x /bin/id ] && CMD_ID="/bin/id" || CMD_ID="/usr/bin/id"
+if [ "$($CMD_ID -u)" != "0" ]; then
+ echo "You need to be root to run $(basename $0)."
+ exit 1
+fi
+
+# Prepare the environment:
+UNATTENDED=${UNATTENDED:-0} # unattended means: never ask questions.
+REFORMAT=${REFORMAT:-0} # do not try to reformat by default
+LOGFILE=${LOGFILE:-/dev/null} # silence by default
+
+# Sanity checks:
+if [ -z "$TARGET" -o -z "$USBIMG" ]; then
+ echo "*** You must specify both the names of usbboot.img and the USB device!"
+ exit 1
+fi
+
+if [ ! -f $USBIMG ]; then
+ echo "*** This is not a useable file: '$USBIMG' !"
+ exit 1
+fi
+
+if [ $REFORMAT -eq 0 ]; then
+ if ! /sbin/blkid -t TYPE=vfat $TARGETPART 1>/dev/null 2>/dev/null ; then
+ echo "*** I fail to find a 'vfat' partition: '$TARGETPART' !"
+ echo "*** If you want to format the USB thumb drive, add the '-f' parameter."
+ exit 1
+ fi
+else
+ if [ ! -b $TARGET ]; then
+ echo "*** Not a block device: '$TARGET' !"
+ exit 1
+ fi
+fi
+
+if mount | grep -q $TARGETPART ; then
+ echo "***"
+ echo "*** Please un-mount $TARGETPART first, then re-run this script!"
+ echo "***"
+ exit 1
+fi
+
+# Check for prerequisites:
+if [ ! -r /usr/lib/syslinux/mbr.bin -o ! -x /usr/bin/syslinux ]; then
+ echo "This script requires that the syslinux package is installed!"
+ exit 1
+fi
+
+# Show the USB device's information to the user:
+if [ $UNATTENDED -eq 0 ]; then
+ [ $REFORMAT -eq 1 ] && DOFRMT="format and " || DOFRMT=""
+
+ echo ""
+ echo "# We are going to ${DOFRMT}use this device - '$TARGET'."
+ /sbin/fdisk -l $TARGET | while read LINE ; do echo "# $LINE" ; done
+ echo ""
+
+ echo "*** ***"
+ echo "*** If this is the wrong drive, then press CONTROL-C now! ***"
+ echo "*** ***"
+
+ read -p "Or press ENTER to continue: " JUNK
+ # OK... the user was sure about the drive...
+fi
+
+# Initialize the logfile:
+cat /dev/null > $LOGFILE
+
+# If we need to format the USB drive, do it now:
+if [ $REFORMAT -eq 1 ]; then
+ echo "--- Formatting $TARGET and creating VFAT partition..."
+ if [ $UNATTENDED -eq 0 ]; then
+ echo "--- Last chance! Press CTRL-C to abort!"
+ read -p "Or press ENTER to continue: " JUNK
+ fi
+ ( reformat $TARGET ) 1>>$LOGFILE 2>&1
+fi
+
+# Create a temporary mount point for the image file:
+mkdir -p /mnt
+MNTDIR1=$(mktemp -d -p /mnt -t img.XXXXXX)
+if [ ! -d $MNTDIR1 ]; then
+ echo "*** Failed to create a temporary mount point for the image!"
+ exit 1
+else
+ chmod 700 $MNTDIR1
+fi
+
+# Create a temporary mount point for the USB thumb drive partition:
+MNTDIR2=$(mktemp -d -p /mnt -t usb.XXXXXX)
+if [ ! -d $MNTDIR2 ]; then
+ echo "*** Failed to create a temporary mount point for the usb thumb drive!"
+ exit 1
+else
+ chmod 700 $MNTDIR2
+fi
+
+# Mount the image file:
+mount -o loop $USBIMG $MNTDIR1
+
+# Mount the vfat partition
+mount $TARGETPART $MNTDIR2
+
+# Check available space:
+USBFREE=$(df -k $TARGETPART | grep "^$TARGETPART" |tr -s ' ' | cut -d' ' -f4)
+IMGSIZE=$(du -k $USBIMG | cut -f1)
+echo "--- Available free space on the the USB drive is $USBFREE KB"
+echo "--- Required free space: $IMGSIZE KB"
+
+# Exit when the image size appears larger than available space:
+if [ $IMGSIZE -gt $USBFREE ]; then
+ echo "*** The USB thumb drive does not have enough free space!"
+ # Cleanup and exit:
+ umount -f $MNTDIR1
+ umount -f $MNTDIR2
+ rmdir $MNTDIR1 $MNTDIR2
+ exit 1
+fi
+
+# Copy files to the USB disk in it's own subdirectory '/syslinux'
+echo "--- Copying files to the USB drive..."
+mkdir -p $MNTDIR2/syslinux
+cp -a $MNTDIR1/* $MNTDIR2/syslinux/
+rm -f $MNTDIR2/syslinux/ldlinux.sys
+
+# Unmount everything:
+umount -f $MNTDIR1
+umount -f $MNTDIR2
+
+# Remove the temporary directories:
+rmdir $MNTDIR1 $MNTDIR2
+
+# Run syslinux and write a good MBR:
+echo "--- Making the USB drive '$TARGET' bootable..."
+( makebootable $TARGET ) 1>>$LOGFILE 2>&1
+/usr/bin/syslinux -s -d /syslinux $TARGETPART 1>>$LOGFILE 2>&1
+dd if=/usr/lib/syslinux/mbr.bin of=$TARGET 1>>$LOGFILE 2>&1
+
+# THE END