Skip to content

Instantly share code, notes, and snippets.

@bcantrill bcantrill/mkusb
Created Dec 21, 2010

Embed
What would you like to do?
#!/bin/ksh -p
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "@(#)mkusb.ksh 1.1 08/05/14 SMI"
#
# mkusb
#
# Given an AK ISO image (output by mkak -I), generate a bootable USB stick
# by mounting the ISO, formatting the USB stick with a Solaris partition,
# copying the ISO content there, and then installing bootable GRUB.
#
if [[ $# -ne 2 ]]; then
echo "Usage: $0 file.iso /dev/rdsk/<usb>p0" >& 2
exit 2
fi
function fail
{
cd /
if [[ -n "$lofidev" ]]; then
umount $rmnt >/dev/null 2>&1
lofiadm -d $lofidev >/dev/null 2>&1
fi
umount $wmnt >/dev/null 2>&1
rmdir $rmnt $wmnt >/dev/null 2>&1
echo "$0: $*" >&2
exit 1
}
iso=$1
pdsk=$2
rdsk=${pdsk%p0}
dsk=$(echo $rdsk | sed 's:/rdsk:/dsk:')
rmnt=/tmp/mkusb-r.$$
wmnt=/tmp/mkusb-w.$$
rm -rf $rmnt $wmnt >/dev/null 2>&1
mkdir -m 0700 $rmnt || fail "failed to mkdir: $rmnt"
mkdir -m 0700 $wmnt || fail "failed to mkdir: $wmnt"
[[ -r $iso ]] || fail "ISO is missing or not readable: $iso"
lofidev=$(lofiadm -a $iso)
[[ -n "$lofidev" ]] || fail "failed to mount ISO: $iso"
mount -F hsfs -o ro $lofidev $rmnt
rlofidev=$(echo $lofidev | sed s/lofi/rlofi/)
rmformat -l $pdsk 2>/dev/null | grep 'Bus: USB' >/dev/null 2>&1 ||
fail "USB device path does not appear to be valid: $pdsk"
echo "Formatting USB device ... \c"
fdisk -B $pdsk || fail "failed to create USB partition"
set -- $(rmformat -l $pdsk 2>/dev/null | \
egrep '(Device|Size):' | cut -d: -f2-)
eval $(prtvtoc $pdsk | grep '^\*' | awk '
$3 == "bytes/sector" { printf("bytes_per_sec=%s\n", $2); }
$3 == "sectors/cylinder" { printf("secs_per_cyl=%s\n", $2); }
$3 == "accessible" { printf("cylinders=%s\n", $2); }')
[[ -z "$bytes_per_sec" || -z "$secs_per_cyl" || -z "$cylinders" ]] && \
fail "failed to read vtoc attributes for $pdsk"
let sectors="$cylinders * $secs_per_cyl"
grub_sec0=0
grub_secs=$secs_per_cyl
grub_part=s8
let root_sec0="$grub_sec0 + $grub_secs"
let root_secs="$sectors - $root_sec0"
root_part=s0
dump_sec0=0
dump_secs=$sectors
dump_part=s2
[[ $root_sec0 -lt $sectors ]] || fail "root disk too small"
fmthard -s - $pdsk >/dev/null <<-EOF
${root_part#s} 2 0x00 $root_sec0 $root_secs
${dump_part#s} 5 0x00 $dump_sec0 $dump_secs
${grub_part#s} 1 0x01 $grub_sec0 $grub_secs
EOF
[[ $? -eq 0 ]] && echo "$*" || fail "failed to format USB stick"
newfs -m 0 $rdsk$root_part </dev/null 2>/dev/null || "failed to newfs USB stick"
mount -F ufs $dsk$root_part $wmnt || fail "failed to mount USB stick"
echo "Copying ISO contents to USB ... "
cd $rmnt && find . -depth -print | cpio -pdVmu $wmnt || fail "cpio failed"
echo "Editing USB boot menu ... \c"
mv -f $wmnt/boot/grub/menu.lst $wmnt/boot/grub/menu.lst.iso
sed 's/ak_media=cd/ak_media=usb/g' $wmnt/boot/grub/menu.lst.iso \
>$wmnt/boot/grub/menu.lst || fail "failed to edit menu file"
chmod 0444 $wmnt/boot/grub/menu.lst
echo "done."
echo "Installing USB boot ... \c"
installgrub -f -m $wmnt/boot/grub/stage1 $wmnt/boot/grub/stage2 \
$rdsk$root_part >/dev/null || fail "installgrub to $rdsk$root_part failed"
cd /
echo "done."
umount $wmnt
umount $rmnt
lofiadm -d $lofidev
echo "done."
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.