From b9bfd78b1956e1c5e0bae3ee183d10b5744a12d7 Mon Sep 17 00:00:00 2001 From: Eric Hameleers Date: Thu, 24 Dec 2015 18:08:19 +0100 Subject: Much enhanced iso2usb script. Two new parameters '--force' and '--persistence'. Read "usb2iso.sh --help". Size of the EFI partition was reduced from 200 to 100 MB. The wait-for-root time in the initrd.img file is changed for both BIOS and UEFI boot; this should make boot work out of the box for most computers. More robustness was added in handling race conditions. Only make the USB stick UEFI-bootable if the ISO file is capable of the same. --- iso2usb.sh | 125 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 37 deletions(-) (limited to 'iso2usb.sh') diff --git a/iso2usb.sh b/iso2usb.sh index d791c98..1ff997a 100644 --- a/iso2usb.sh +++ b/iso2usb.sh @@ -24,6 +24,12 @@ # Be careful: set -e +# Set to '1' if you want to ignore all warnings: +FORCE=0 + +# By default, we use 'persistence' as the name of the persistence directory: +PERSISTENCE="persistence" + # Set to '1' if the script should not ask any questions: UNATTENDED=0 @@ -39,6 +45,10 @@ EFIMNT="" ISOMNT="" USBMNT="" +# +# -- function definitions -- +# + # Clean up in case of failure: cleanup() { # Clean up by unmounting our loopmounts, deleting tempfiles: @@ -65,9 +75,11 @@ cat < Full path to the ISO image file # -o|--outdev The device name of your USB drive +# -p|--persistence Custom name of the 'persistence' directory # -u|--unattended Do not ask any questions # -v|--verbose Show verbose messages # -w|--wait Pause boot seconds to initialize USB @@ -80,6 +92,42 @@ cat </dev/null) + [ "$OLDWAIT" = "$WAIT" ] && return + + if [ -z "$IMGDIR" ]; then + # Create a temporary extraction directory for the initrd: + mkdir -p /mnt + IMGDIR=$(mktemp -d -p /mnt -t alienimg.XXXXXX) + if [ ! -d $IMGDIR ]; then + echo "*** Failed to create a temporary extraction directory for the initrd!" + exit 1 + fi + fi + chmod 711 $IMGDIR + + echo "--- Extracting Slackware initrd and adding rootdelay for USB..." + cd ${IMGDIR} + gunzip -cd ${USBMNT}/boot/initrd.img \ + | cpio -i -d -H newc --no-absolute-filenames + echo "--- Updating 'waitforroot' time from '$OLDWAIT' to '$WAIT':" + echo ${WAIT} > wait-for-root + echo "--- Compressing the initrd image again:" + chmod 0755 ${IMGDIR} + find . |cpio -o -H newc |gzip > ${USBMNT}/boot/initrd.img + cd - 2>/dev/null + rm -rf $IMGDIR/* +} # End of update_initrd() + +# +# -- end of function definitions -- +# + # Parse the commandline parameters: if [ -z "$1" ]; then showhelp @@ -87,6 +135,10 @@ if [ -z "$1" ]; then fi while [ ! -z "$1" ]; do case $1 in + -f|--force) + FORCE=1 + shift + ;; -h|--help) showhelp exit @@ -99,6 +151,10 @@ while [ ! -z "$1" ]; do TARGET="$2" shift 2 ;; + -p|--persistence) + PERSISTENCE="$2" + shift 2 + ;; -u|--unattended) UNATTENDED=1 shift @@ -121,7 +177,7 @@ done # Before we start: [ -x /bin/id ] && CMD_ID="/bin/id" || CMD_ID="/usr/bin/id" -if [ "$($CMD_ID -u)" != "0" ]; then +if [ "$($CMD_ID -u)" != "0" -a $FORCE -eq 0 ]; then echo "*** You need to be root to run $(basename $0)." exit 1 fi @@ -132,15 +188,15 @@ if [ -z "$TARGET" -o -z "$SLISO" ]; then exit 1 fi -if [ ! -f $SLISO ]; then +if [ ! -f $SLISO -a $FORCE -eq 0 ]; then echo "*** This is not a useable file: '$SLISO' !" exit 1 fi -if [ ! -b $TARGET ]; then +if [ ! -b $TARGET -a $FORCE -eq 0 ]; then echo "*** Not a block device: '$TARGET' !" exit 1 -elif [ "$(echo ${TARGET%[0-9]})" != "$TARGET" ]; then +elif [ "$(echo ${TARGET%[0-9]})" != "$TARGET" -a $FORCE -eq 0 ]; then echo "*** You need to point to the USB device, not a partition ($TARGET)!" exit 1 fi @@ -169,7 +225,7 @@ cat </dev/null | while read LINE ; do echo "# $LINE" ; done +echo q |/sbin/gdisk -l $TARGET 2>/dev/null | while read LINE ; do echo "# $LINE" ; done if [ $UNATTENDED -eq 0 ]; then cat </dev/null |grep EFI |tr -s ' ' | cut -d' ' -f 2) if [ -n "$EFIOFFSET" ]; then # Mount the EFI partition so we can retrieve the EFI bootloader: @@ -237,6 +295,8 @@ if [ -n "$EFIOFFSET" ]; then if [ ! -f ${EFIMNT}/EFI/BOOT/bootx64.efi ]; then echo "-- Note: UEFI boot file 'bootx64.efi' not found on ISO." echo "-- UEFI boot will not be supported" + else + EFIBOOT=1 fi fi @@ -250,22 +310,30 @@ else chmod 711 $USBMNT fi -# Mount the EFI partition and copy the EFI boot image to it: -/sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${USBMNT} -mkdir -p ${USBMNT}/EFI/BOOT -cp ${EFIMNT}/EFI/BOOT/bootx64.efi ${USBMNT}/EFI/BOOT +# Loop-mount the ISO (or 1st partition if this is a hybrid ISO): +/sbin/mount -o loop ${SLISO} ${ISOMNT} + +if [ $EFIBOOT -eq 1 ]; then + # Mount the EFI partition and copy /EFI as well as /boot directories into it: + /sbin/mount -t vfat -o shortname=mixed ${TARGET}2 ${USBMNT} + mkdir -p ${USBMNT}/EFI/BOOT + rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${USBMNT}/EFI/BOOT/ + mkdir -p ${USBMNT}/boot + rsync -rlptD ${ISOMNT}/boot/* ${USBMNT}/boot/ + # Add more USB WAIT seconds to the initrd: + update_initrd ${USBMNT}/boot/initrd.img +fi + +# No longer needed: /sbin/umount ${USBMNT} /sbin/umount ${EFIMNT} # Mount the Linux partition: /sbin/mount -t auto ${TARGET}3 ${USBMNT} -# Loop-mount the ISO (or 1st partition if this is a hybrid ISO): -/sbin/mount -o loop ${SLISO} ${ISOMNT} - # Copy the ISO content into the USB Linux partition: echo "--- Copying files from ISO to USB... takes some time." -rsync -a ${RVERBOSE} ${ISOMNT}/* ${USBMNT}/ +rsync -a ${RVERBOSE} --exclude=EFI ${ISOMNT}/* ${USBMNT}/ # Write down the version of the ISO image: VERSION=$(iso-info ${SLISO} |grep Application |cut -d: -f2- 2>/dev/null) @@ -273,28 +341,11 @@ if [ -n "$VERSION" ]; then echo "$VERSION" > ${USBMNT}/.isoversion fi -# Create a temporary extraction directory for the initrd: -mkdir -p /mnt -IMGDIR=$(mktemp -d -p /mnt -t alienimg.XXXXXX) -if [ ! -d $IMGDIR ]; then - echo "*** Failed to create a temporary extraction directory for the initrd!" - exit 1 -else - chmod 711 $IMGDIR -fi - -# USB boot medium needs a few seconds boot delay or else the overlay will fail: -echo "--- Extracting Slackware initrd and adding rootdelay for USB..." -cd ${IMGDIR} -gunzip -cd ${USBMNT}/boot/initrd.img |cpio -i -d -H newc --no-absolute-filenames -echo ${WAIT} > wait-for-root -echo "--- Compressing the initrd image again:" -chmod 0755 ${IMGDIR} -find . |cpio -o -H newc |gzip > ${USBMNT}/boot/initrd.img -cd - 2>/dev/null +# Add more USB WAIT seconds to the initrd: +update_initrd ${USBMNT}/boot/initrd.img # Create persistence directory: -mkdir -p ${USBMNT}/persistence +mkdir -p ${USBMNT}/${PERSISTENCE} # Use extlinux to make the USB device bootable: echo "--- Making the USB drive '$TARGET' bootable using extlinux..." -- cgit v1.2.3