Basti’s Buggy Blog

Poking at software.

Boot Arch Linux ISOs from Grub

The Goal

Motivation: Boot Arch Linux installation ISOs placed on the filesystem (no USB-Stick) from Grub. In case I manage to wreck my Arch Linux installation, I should be able to resolve any issues by booting into the ISO image right from Grub.

  • I should be able to place Arch ISO images in a directory which is not on the /boot partition
  • The ISOs should be easily replaceable
  • Multiple ISOs should be supported

The process of setting up Grub boot entries for Arch Linux ISO images is well documented in the Arch Wiki. This article only adds a convenience script which generates the Grub boot entries.

How-To

Create an Unencrypted ISO Partition

Since my /boot partition was to small to accommodate multiple 600MB ISOs, I created a separate unencrypted ext4 partition on my SSD. This partition serves the single purpose of storing the ISO images in the root folder.

To uniquely identify the partition, note the filesystem UUID (not to be confused with the partition UUID). The UUID can be obtained with the blkid command:

sh@dsh ~ sudo blkid
/dev/nvme0n1p3: UUID="..." BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="isos" PARTUUID="..."
...
Note the UUID value.

Create the Grub ISO Scanner Script

This script will

  1. Mount the partition with the given UUID
  2. Scan the ISO images on the root directory of the partition
  3. Generate a Grub boot entry for each ISO image

Entries for new ISO files will only be generated when the grub-mkconfig command is executed. Anytime you change either the script or the ISO images, generate the Grub configuration by executing:

sh@dsh ~ sudo grub-mkconfig -o /boot/grub/grub.cfg

Place the following script in the /etc/grub.d/ directory. It will automatically be called when a new Grub configuration is generated.

 /etc/grub.d/42_isos

#!/bin/sh

# insert your UUID here
ISO_FS_UUID="..."
# temporary mount path for scanning the iso images
TMP_MOUNT_PATH=/mnt/grub-isos

ISO_FS_PATH="/dev/disk/by-uuid/$ISO_FS_UUID"

mkdir -p "$TMP_MOUNT_PATH"
if ! mount -o ro "$ISO_FS_PATH" "$TMP_MOUNT_PATH" >/dev/null ; then
    echo "Failed to mount partition containing ISO images, skipping ISOs..." >&2
    exit 0
fi

echo "Generating ISO image boot entries..." >&2
for f in "$TMP_MOUNT_PATH"/*.iso ; do
    ISO_NAME=`basename $f`
    echo "Found ISO image: $ISO_NAME" >&2
    cat <<EOF
menuentry "[ISO] $ISO_NAME" {
    insmod ext2
    search --no-floppy --set=isopart --fs-uuid $ISO_FS_UUID
    set isofile="/$ISO_NAME"
    set imgdevpath="/dev/disk/by-uuid/$ISO_FS_UUID"
    loopback loop0 (\$isopart)\$isofile
    linux (loop0)/arch/boot/x86_64/vmlinuz-linux img_dev=\$imgdevpath img_loop=\$isofile earlymodules=loop
    initrd (loop0)/arch/boot/intel-ucode.img (loop0)/arch/boot/amd-ucode.img (loop0)/arch/boot/x86_64/initramfs-linux.img
}
EOF
done

umount "$TMP_MOUNT_PATH"

That’s it. After executing the grub-mkconfig command you should be able to reboot and select your Arch ISOs. The script can be adjusted for different ISOs by using the respective boot parameters required by the Linux distribution.

See Also