#!/bin/bash
# $Id: build_bootable_USB.sh 3498 2011-12-03 01:28:47Z skylar $
# This file is part of BCCD, an open-source live CD for computational science
# education.
#
# Copyright (C) 2010 Andrew Fitz Gibbon, Paul Gray, Kevin Hunter, Dave Joiner,
# Sam Leeman-Munk, Tom Murphy, Charlie Peck, Skylar Thompson, & Aaron Weeden
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#This script must be run as superuser
if [ `id -u` != 0 ]; then
echo "$0: ERROR: superuser privileges required."
exit
fi
#Parse command line args
if [ $2 ]; then
DRIVE=$1
ISO_PATH=$2
else
echo -e "USAGE:\n $0 "
exit
fi
#Verify that files exist
if [ ! -e $DRIVE ]; then
echo -e "$0: ERROR: $DRIVE: file not found."
exit
fi
if [ ! -f $ISO_PATH ]; then
echo -e "$0: ERROR: $ISO_PATH: file not found."
exit
fi
echo '---> Checking dependencies'
for dep in mkfs.vfat parted syslinux rsync du fdisk; do
if test -z `which $dep`; then
echo "$0: ERROR: Missing dependency: $dep"
exit
else
if [ $dep == "mkfs.vfat" ]; then
mkfs=`which $dep`
else
eval $dep=`which $dep`
fi
fi
done
#Get sizes of drive and ISO
echo '---> Get drive/iso sizes'
DRIVE_SIZE=$((`$fdisk -l $DRIVE | grep "^Disk $DRIVE" | awk '{print $5}'`/1024))
ISO_SIZE=`$du -k $ISO_PATH | awk '{print $1}'`
#Exit if ISO is too big for drive
if [ $ISO_SIZE -gt $DRIVE_SIZE ]; then
echo "$0: ERROR: ISO is too big for drive"
exit
fi
echo "---> Ensuring ${DRIVE}1 is not mounted"
umount ${DRIVE}1
echo '---> Removing existing partitions'
PARTITIONS=`$parted $DRIVE print | grep ^\ [0-9] | awk '{print $1}'`
if [ "$PARTITIONS" ]; then
for i in $PARTITIONS; do
echo "removing partition $i:"
$parted $DRIVE rm $i;
done
fi
echo '---> Creating the partition'
# parted parses -1 as end of $DRIVE. Double quoted to make sure parted doesn't
# read it as a command-line option.
$parted $DRIVE mkpart primary "1 -1"
echo "---> Wait for ${DRIVE}1 to manifest"
while ! test -b ${DRIVE}1; do sleep 1; done
echo '---> Format the partition'
$mkfs ${DRIVE}1
echo '---> Making partition bootable'
$parted $DRIVE set 1 boot on
echo "---> Wait for ${DRIVE}1 to come back again"
while ! test -b ${DRIVE}1; do sleep 1; done
echo '---> Copying mbr.bin'
mbr=`find /usr/lib -name mbr.bin | head -1`
cat $mbr >> $DRIVE
echo '---> Running syslinux'
$syslinux "${DRIVE}1"
if [ $? != 0 ]; then
echo '---> ERROR: Installing syslinux bootloader failed.'
fi
echo '---> Making temporary directories'
ISO_DIR=`mktemp -d iso-XXXXXXXX`
USB_DIR=`mktemp -d usb-XXXXXXXX`
echo '---> Mounting image and partition to temporary directories'
mount -o loop $ISO_PATH $ISO_DIR/
mount ${DRIVE}1 $USB_DIR/
echo '---> Copying files from image to partition'
echo '---> This will take a while...'
$rsync -Plarv $ISO_DIR/ $USB_DIR/
cp $ISO_DIR/boot/isolinux/* $USB_DIR/
mv $USB_DIR/isolinux.cfg $USB_DIR/syslinux.cfg
echo '---> Unmounting image and partition'
umount $ISO_DIR/
umount $USB_DIR/
echo '---> Removing temporary directories'
rm -r $ISO_DIR/
rm -r $USB_DIR/
echo '---> Script finished.'