GRUB Boot from ISO

Next are two separate GRUB menus (each are within menuentry {} stanzas). The first points to a preseed configuration file and starts a partially automated Debian install, while the other just boots the Debian installer with no preseed file and acts like an "Expert" mode so you can choose every install option by hand.

Up to this point, the GRUB options were pretty similar to other GRUB configurations, but here is where that changes. Next in each menu, you define a loopback device GRUB will use:


loopback loop (hd0,msdos2)$isofile

Now, whenever you refer to (loop) further in the config, GRUB knows to access the loopback filesystem labeled loop, which points to (hd0,msdos2)/install_dvd1.iso. The next two lines should look pretty familiar to someone who has worked with Linux GRUB configuration before, but with a twist:


linux (loop)/install.amd/vmlinuz vga=788 auto=true
 ↪file=/media/preseed.cfg -- quiet
initrd (loop)/install.amd/initrd.gz

In the first line, you define what kernel to boot and what options to pass it, and in the following line, you point GRUB to the initrd file you want it to use. The main difference here though is that you precede each file path with (loop) to instruct GRUB to look in that loopback filesystem for the file.

Once this configuration finds its way into grub.cfg, you should see the two new menu options in place the next time you boot. Now the first time I tried to boot the most recent Debian installer this way, I ran into a bit of a problem. It turns out that the initrd that comes on the ISO itself does not contain the installer scripts you need to install from an ISO on a hard drive. It assumes you will boot only off a DVD or USB disk. Because of that, I discovered I had to download a different Debian installer initrd and put it on the rescue disk for things to work. I was able to find an initrd that worked here.

Of course, with that new initrd.gz file at the root of my rescue partition, I had to change my GRUB config a little bit to point to it:


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 /initrd.gz
}
menuentry "Install OS (Expert)" {
 loopback loop (hd0,msdos2)$isofile
 linux (loop)/install.amd/vmlinuz vga=788 -- quiet
 initrd /initrd.gz
}

Note that the initrd lines now point to /initrd.gz. Since I already defined the root variable earlier in the config, it knows to look on hd0,msdos2 for the file. Once this new initrd was in place, I was in business, and the installer worked as expected. If you want to use this with a different installer, just make sure that once the kernel boots up, it has the ability to scan disks for an installer ISO to use.

______________________

Kyle Rankin is SVP of Security and Infrastructure at Zero, 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