GRUB Boot from ISO

Last year I worked on a project to add an OEM-style rescue partition to a computer. Where most OEM installs have a custom program that just rewrites an install image over the top of the partition, in this case, everything was based on open-source software. This rescue partition would be only a few gigabytes in size—big enough to contain the install DVD ISO image and a few preseed files to help automate the install. If users ever wanted to get back to the factory-installed version of the operating system, they could select a special option from the GRUB menu that would boot off the ISO and start the install as though they had used a USB key or DVD.

If you read some past guides on how to boot an ISO from GRUB, you will find a number of pretty complicated instructions in some cases because they were writing for older versions of GRUB. With the recent versions of GRUB2, booting from a standard ISO is fortunately not that complicated. I base my example here off a recent Debian Stretch install DVD, but the same steps should work for other distributions and install ISOs with some tweaks.

Create the Partition

The first step is to create the rescue partition. In my case, I automated my install with a preseed script, but basically I just created a partition that was big enough to hold the install DVD. I made sure to give it a label so I could tell it apart from other disks later on and made it the second partition on the disk. Because I was doing all of this via an automated means, I ended up using dd to create an image of the install DVD that was currently in use as an end-of-install script and dumped it to the root of that partition in a file called install_dvd1.iso. Of course, you could just copy over your ISO directly to the disk if you do this from a system that already has an OS on it.

Build the GRUB Config

The next step was to build a GRUB config that would mount the ISO loopback and boot off the kernel and initrd file within that ISO. On Debian-based systems, you can add bash scripts that output extra GRUB configuration to /etc/grub.d/ and run update-grub to build a new grub.cfg file. But, you also could just edit grub.cfg directly or otherwise use your distribution's GRUB configuration scripts to add the following menu items:


set root='hd0,msdos2'
set isofile="/install_dvd1.iso"
menuentry "Install OS" {
 loopback loop (hd0,msdos2)$isofile
 linux (loop)/install.amd/vmlinuz vga=788 auto=true
  ↪file=/media/preseed.cfg -- quiet
 initrd (loop)/install.amd/initrd.gz
}
menuentry "Install OS (Expert)" {
 loopback loop (hd0,msdos2)$isofile
 linux (loop)/install.amd/vmlinuz vga=788 -- quiet
 initrd (loop)/install.amd/initrd.gz
}

Let's break this GRUB configuration down a bit. First, you set two variables: the root partition GRUB will use (the second partition on the first disk, which GRUB refers to as hd0,msdos2) and the ISO file:


set root='hd0,msdos2'
set isofile="/install_dvd1.iso"

______________________

Kyle Rankin is VP of engineering operations at Final, Inc., the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin