Skip to content

Instantly share code, notes, and snippets.

@squimrel
Last active June 27, 2017 12:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save squimrel/8959bf78399f2365d801cd0c56c7b840 to your computer and use it in GitHub Desktop.
Save squimrel/8959bf78399f2365d801cd0c56c7b840 to your computer and use it in GitHub Desktop.
Proof-of-concept of approach #1
#!/bin/sh
# This is a proof of concept. It was not designed to be beautiful, portable or
# anything like that.
readonly SOURCE="${1}"
if [ -z "${SOURCE}" ]; then
echo "Usage: ${0} <iso image> [/dev/sdX|vm name]"
exit 1
fi
DEVICE=""
# Name of the virtual machine used for manual testing.
VMNAME="Fedora Live WS"
if [ -n "${2}" ]; then
if echo "${2}" | grep -q "^/"; then
readonly DEVICE="${2}"
echo "Writing ${SOURCE} to ${DEVICE}"
else
VMNAME="${2}"
fi
fi
readonly VMNAME
readonly MOUNTPOINT="$(mktemp -d)"
readonly MOUNTPOINT2="$(mktemp -d)"
# Extract iso.
mkdir -p "${MOUNTPOINT}"
sudo mount -o loop "${SOURCE}" "${MOUNTPOINT}"
readonly DIRECTORY="$(cat "${MOUNTPOINT}/EFI/BOOT/grub.cfg" | grep search | cut -d "'" -f2)"
mkdir -p "${DIRECTORY}"
rsync -av --delete "${MOUNTPOINT}/" "${DIRECTORY}"
sudo umount "${MOUNTPOINT}"
cd "${DIRECTORY}"
sudo mount -o loop ./images/efiboot.img "${MOUNTPOINT}"
sudo mount -o loop ./images/macboot.img "${MOUNTPOINT2}"
sudo sed -i \
"s#rd.live.image#& rd.live.overlay=LABEL=OVERLAY:/OVERLAY.IMG#g" \
./isolinux/isolinux.cfg ./EFI/BOOT/grub.cfg ./isolinux/grub.conf \
"${MOUNTPOINT}/EFI/BOOT/grub.cfg" "${MOUNTPOINT2}/EFI/BOOT/grub.cfg" \
"${MOUNTPOINT2}/System/Library/CoreServices/grub.cfg"
sudo umount "${MOUNTPOINT}"
sudo umount "${MOUNTPOINT2}"
cd -
readonly LABEL="${DIRECTORY}"
readonly TARGET="${LABEL}.iso"
rm "${TARGET}"
mkisofs \
-eltorito-boot "isolinux/isolinux.bin" \
-eltorito-catalog "isolinux/boot.cat" \
-input-charset utf-8 \
-boot-load-size 4 \
-boot-info-table \
-no-emul-boot \
-eltorito-alt-boot -efi-boot "images/efiboot.img" -no-emul-boot \
-eltorito-alt-boot -efi-boot "images/macboot.img" -no-emul-boot \
-rock -joliet \
-volid "${LABEL}" \
-translation-table \
-graft-points \
-output "${TARGET}" "${DIRECTORY}"
isohybrid --uefi --mac "${TARGET}"
implantisomd5 "${TARGET}"
IMAGE=""
if [ -z "${DEVICE}" ]; then
IMAGE="${LABEL}.img"
DEVICE="${IMAGE}"
fi
readonly IMAGE
if [ -n "${IMAGE}" ]; then
echo "Creating ${IMAGE}.."
dd "if=${TARGET}" "of=${IMAGE}" "bs=4M"
# Make sure the fake drive is larger than the iso.
fallocate -l 4000M "${IMAGE}"
fi
# Add fat partition.
echo -e "n\np\n\n\n\nt\n\nb\nw\n" | sudo fdisk "${DEVICE}"
if [ -n "${IMAGE}" ]; then
readonly DEVICE="$(sudo losetup --partscan --show -f "${IMAGE}")p"
fi
sudo mkfs.fat -i DEAFBEEF -n OVERLAY "${DEVICE}4"
sudo mount "${DEVICE}4" "${MOUNTPOINT}"
SIZE="$(df | grep "${DEVICE}4" | sed -r "s/[^ ]+ +([0-9]+).+/\1/g")"
# Maximum size is 4 gb because of the fat32 limitation.
if [ "${SIZE}" -gt "$((4095 * 1024))" ]; then
SIZE="$((4095 * 1024))"
fi
SIZE="$((${SIZE} / 4))"
readonly SIZE
echo "Creating overlay file ($((${SIZE} * 4)) kB).."
sudo dd "if=/dev/zero" "of=${MOUNTPOINT}/OVERLAY.IMG" "oflag=direct" \
"count=${SIZE}" "bs=4K"
sudo umount "${MOUNTPOINT}"
if [ -n "${IMAGE}" ]; then
sudo losetup -d "$(echo "${DEVICE}" | sed "s/.$//")"
implantisomd5 --force "${IMAGE}"
# For manual testing in VirtualBox.
readonly VDISK="${LABEL}.vdi"
rm -f "${VDISK}"
VBoxManage convertfromraw --format VDI "${IMAGE}" "${VDISK}"
# Reattach VDI. It seems like VirtualBox can't boot from usb that's why it's
# connected over sata.
VBoxManage storageattach "${VMNAME}" --storagectl SATA --port 0 --medium none
VBoxManage closemedium disk "${VDISK}"
VBoxManage storageattach "${VMNAME}" --storagectl SATA --port 0 --type hdd \
--medium "${VDISK}"
else
sudo implantisomd5 --force "${DEVICE}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment