Skip to content

Instantly share code, notes, and snippets.

@rduplain
Last active July 23, 2021 21:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rduplain/69c82c2102d6f83915e9c8cdf3f4f928 to your computer and use it in GitHub Desktop.
Save rduplain/69c82c2102d6f83915e9c8cdf3f4f928 to your computer and use it in GitHub Desktop.
Bootloader configuration for multiple .iso files on a USB drive.
#!/bin/sh
# Use grub to boot .iso files directly from /boot/iso.
#
# This file lives at /etc/grub.d/25_iso and is executable.
#
# Open .iso files to inspect internal /boot files for grub config hints.
# /boot is on the third partition of a gpt-partitioned USB drive.
ISO_PART_UUID="0a5086cd-8fdf-4ae0-a248-67411ebbbb18" # UUID of /boot `blkid`.
ISO_PART_NUMBER=3
ISO_HINT_BAREMETAL="ahci0,gpt${ISO_PART_NUMBER}"
ISO_HINT_BIOS="hd0,gpt${ISO_PART_NUMBER}"
ISO_HINT_EFI="hd0,gpt${ISO_PART_NUMBER}"
iso() {
filename="$1"
class="$2"
if [ $# -ge 3 ]; then
platform="$3"
else
platform=""
fi
if [ -n "$platform" ]; then
echo "if [ \"\${grub_platform}\" = \"${platform}\" ]; then"
fi
cat <<EOF
menuentry "$filename" --class "$class" {
gfxmode \$linux_gfx_mode
insmod part_gpt
insmod ext2
set iso="/iso/$filename"
set root=$ISO_HINT_BIOS
if [ x\$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=$ISO_HINT_BIOS --hint-efi=$ISO_HINT_EFI --hint-baremetal=$ISO_HINT_BAREMETAL $ISO_PART_UUID
else
search --no-floppy --fs-uuid --set=root $ISO_PART_UUID
fi
loopback loop (\${root})\${iso}
EOF
cat -
echo "}"
if [ -n "$platform" ]; then
echo 'fi'
fi
echo
}
freenas() {
iso "$1" freebsd pc <<EOF
insmod ufs2
insmod iso9660
kfreebsd (loop)/boot/kernel/kernel
kfreebsd_loadenv (loop)/boot/device.hints
kfreebsd_loadenv (loop)/boot/loader.conf
kfreebsd_module (\${root})\${iso} type=mfs_root
set FreeBSD.vfs.root.mountfrom=cd9660:/dev/md0
set FreeBSD.vfs.root.mountfrom.options=ro
EOF
}
iso FreeDOS-1.3-LIVE.iso windows pc <<EOF
insmod fat
linux16 (loop)/isolinux/memdisk
initrd16 (loop)/isolinux/fdlive.img
EOF
freenas FreeNAS-11.2-U8.iso
freenas FreeNAS-11.3-U5.iso
iso kali-linux-2021.2-live-amd64.iso kali <<EOF
linux (loop)/live/vmlinuz boot=live components quiet splash noeject findiso=\$iso
initrd (loop)/live/initrd.img
EOF
iso kali-linux-2021.2-live-i386.iso kali pc <<EOF
linux (loop)/live/vmlinuz boot=live components quiet splash noeject findiso=\$iso
initrd (loop)/live/initrd.img
EOF
iso KNOPPIX_V9.1DVD-2021-01-25-EN.iso knoppix pc <<EOF
linux (loop)/boot/isolinux/linux bootfrom=/dev/sda1\$iso acpi=off keyboard=us language-us
initrd (loop)/boot/isolinux/minirt.gz
EOF
freenas TrueNAS-12.0-U4.1.iso
iso ubuntu-20.04.2.0-desktop-amd64.iso ubuntu <<EOF
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=\$iso quiet noeject noprompt splash
initrd (loop)/casper/initrd
EOF
iso ubuntu-20.04.2-live-server-amd64.iso ubuntu <<EOF
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=\$iso quiet noeject noprompt splash
initrd (loop)/casper/initrd
EOF
@rduplain
Copy link
Author

rduplain commented Jul 7, 2021

This is how I manage my multi-boot USB drive; it's a personal configuration.

The KNOPPIX and i386 .iso menu entries require "legacy" (or "CSM") boot from BIOS on x86_64 systems (else GRUB complains about the 64-bit kernel and doesn't boot); to support this, I have a 2MB GRUB BIOS partition (GPT type ef02) alongside the EFI partition so that the resulting grub.cfg can be read in either "legacy" or UEFI modes.

Adjust ISO_PART_UUID and ISO_PART_NUMBER for the target USB drive. Download .iso files to the /iso directory inside the boot partition (typically mounted at /boot/iso).

Useful articles:

Protip: procure a USB 3.0 drive with (well) over 100MB/s read/write speeds; USB thumb drives have arrived.

@rduplain
Copy link
Author

@rduplain
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment