Multiboot USB Stick GRUB Stanzas

Please take a look at Setting up a Multi-Boot Linux USB Stick before reading this.

Booting an ISO (as an ISO, rather than burned to a USB stick or to optical media) requires some basic assistance from the creator of the ISO. They need to be aware that this is a possibility, and provide a way for the software on the ISO to understand how to locate all the files it needs if the ISO hasn't been burned and mounted in the intended way. Unfortunately, there's zero consistency among Linux distros about how to do this - or even whether it should be done at all. I've included my menuentry entries for various Linux distros (and some oddballs) below. The order will seem odd: this is because I'm working from most successful to least successful. "Success" - such as it is - is very strongly tied to specific versions of ISOs: if you're reading this trying to get a newer ISO of one of the ones below working ... well, there are no guarantees, things often change.

MemTest86+

menuentry "MemTest86+ 5.01 Binary (linux16)" --hotkey=M {
    linux16 /boot/iso/memtest86+-5.01.bin
}

Available from http://www.memtest.org/#downiso . This has been working great - note the use of linux16 rather than the more common linux. This can be started by pressing the letter "M" (has to be capital "M", not lower case) at the GRUB menu. This is a binary rather than an ISO, but they also provide an ISO that worked fine too - I prefer the binary.

Fedora

menuentry 'Fedora LXDE Live i386 25-1.3' {
    set isofile='/boot/iso/Fedora-LXDE-Live-i386-25-1.3.iso'
    loopback loop $isofile
    linux (loop)/isolinux/vmlinuz root=live:CDLABEL=Fedora-LXDE-Live-25-1-3 iso-scan/filename=$isofile rd.live.image quiet
    initrd (loop)/isolinux/initrd.img
}

menuentry 'Fedora Workstation Live x86_64 25-1.3 - GOOD' {
    set isofile='/boot/iso/Fedora-Workstation-Live-x86_64-25-1.3.iso'
    loopback loop $isofile
    linux (loop)/isolinux/vmlinuz root=live:CDLABEL=Fedora-WS-Live-25-1-3 iso-scan/filename=$isofile rd.live.image quiet
    initrd (loop)/isolinux/initrd.img
}

I should be thanking someone for this - maybe Archwiki, I don't remember. Anyway, works great. This is a good point at which to remind anyone reading this that trying to run a 64-bit installer on a 32-bit system will result in immediate silent failure (no harm will be caused to your machine ... I've done it many times).

SystemRescueCD

menuentry "SystemRescueCd 32bit" {
    set iso="/boot/iso/systemrescuecd-x86-5.0.0.iso"
    loopback loop $iso
    linux (loop)/isolinux/rescue32 isoloop=$iso setkmap=us
    initrd (loop)/isolinux/initram.igz
}

menuentry "SystemRescueCd 64bit" {
    set iso="/boot/iso/systemrescuecd-x86-5.0.0.iso"
    loopback loop $iso
    linux (loop)/isolinux/rescue64 isoloop=$iso setkmap=dvorak
    initrd (loop)/isolinux/initram.igz
}

I believe this one is courtesy of Daniel. Works well. I added (and checked!) the 64-bit version. NOTE: I changed the keymap on the second entry to "Dvorak", so if you blindly copy-and-paste these entries you'll really hate the keymap on one or the other of these.

GPartEd Live

A great live distribution for editing your partitions. Editing your partitions from an OS running from the same hard drive as the partitions you want to edit doesn't work. Live media is particularly good for this purpose.

menuentry "GPartEd Live 0.22.0-2 32-bit" {
    set isofile="/boot/iso/gparted-live-0.28.1-1-i686.iso"
    loopback loop $isofile
    linux (loop)/live/vmlinuz boot=live union=overlay username=user config components quiet noswap noeject toram=filesystem.squashfs ip=  nosplash findiso=$isofile
    initrd (loop)/live/initrd.img
}

menuentry "GPartEd Live 0.22.0-2 amd64" {
    set isofile="/boot/iso/gparted-live-0.28.1-1-amd64.iso"
    loopback loop $isofile
    linux (loop)/live/vmlinuz boot=live union=overlay username=user config components quiet noswap noeject toram=filesystem.squashfs ip=  nosplash findiso=$isofile
    initrd (loop)/live/initrd.img
}

Works well.

Kali Linux

"Kali Linux is a Debian-derived Linux distribution designed for digital forensics and penetration testing." (Wikipedia). I only tried the 32-bit version:

menuentry "Kali Linux 2017.1 (32-bit)" {
    set isofile="/boot/iso/kali-linux-2017.1-i386.iso"
    loopback loop $isofile
    linux (loop)/live/vmlinuz boot=live findiso=$isofile noconfig=sudo username=root hostname=kali
    initrd (loop)/live/initrd.img
}

menuentry "Kali Linux 2017.1 (32-bit PAE)" {
    set isofile="/boot/iso/kali-linux-2017.1-i386.iso"
    loopback loop $isofile
    linux (loop)/live/vmlinuz-4.9.0-kali3-686-pae boot=live findiso=$isofile noconfig=sudo username=root hostname=kali
    initrd (loop)/live/initrd.img-4.9.0-kali3-686-pae
}

Their use of GNOME 3 makes it painfully slow to boot on old low end laptops - I find this notable because almost every other Linux distro listed here is faster. Boots fine on a 64-bit system.

Darik's Boot and Nuke

A distro whose sole purpose is to do a high security wipe of (spinning) disks attached to the computer you're booting. Available from https://dban.org .

menuentry "Darik's Boot and Nuke (DBAN) 2.3.0 ~2016-09 (NOT autonuke!)" {
    set isofile="/boot/iso/dban-2.3.0_i586.iso"
    loopback loop $isofile
    linux (loop)/dban.bzi nuke="dwipe" silent vga=785
}

Starts slowly, but works fine.

The standard DBAN GRUB menu has many different options, one of which is "autonuke". If you boot that, it IMMEDIATELY starts to wipe every HD it finds. I didn't even want that as an option: the item above comes up to a menu system that asks you which partitions you want to wipe.

Ubuntu and Derivatives

menuentry "Ubuntu 16.04 - 64bit Live Mode + Desktop Installer" {
    set iso="/boot/iso/ubuntu-16.04.2-desktop-amd64.iso"
    loopback loop $iso
    linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$iso noprompt noeject
    initrd (loop)/casper/initrd.lz
}

menuentry "Lubuntu 16.04 - i386 Live Mode + Desktop Installer" {
    set iso="/boot/iso/lubuntu-16.04.2-desktop-i386.iso"
    loopback loop $iso
    linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$iso noprompt noeject
    initrd (loop)/casper/initrd.lz
}

Note that this is both 64-bit and 32-bit, and both regular Ubuntu and Lubuntu - but that the stanzas are otherwise the same and work fine. Ubuntu happily seems well set up to boot from ISO if you know the invocation.

Knoppix

menuentry "KNOPPIX 7.2.0 CD 32-bit-only" {
    set iso="/boot/iso/KNOPPIX_V7.2.0CD-2013-06-16-EN.iso"
    loopback loop $iso
    linux (loop)/boot/isolinux/linux bootfrom=/mnt-iso/$iso acpi=off keyboard=us lang=us
    initrd (loop)/boot/isolinux/minirt.gz
}

This entry works great on 32-bit systems (although you'll have a long wait before it goes to graphical mode), but kernel-panics on 64-bit systems. This is unusual: most 32-bit versions of Linux will run fine on 64-bit systems (although they may not see all the memory the system supports). It's also old - the last of the Knoppix CDs. I've included it because there's a problem related to using the Knoppix DVDs and this may still be useful.

menuentry "Knoppix 7.7.1 DVD 32-bit-only" {
    insmod ext2
    set iso="/KNOPPIX_V7.7.1DVD-2016-10-22-EN.iso"
    loopback loop (hd0,msdos2)$iso
    linux (loop)/boot/isolinux/linux bootfrom=/mnt-iso/$iso lang=en apm=power-off nomce libata.force=noncq hpsa.hpsa_allow_any=1 loglevel=1
    initrd (loop)/boot/isolinux/minirt.gz
}

Huge caveat: Multiboot USB sticks are usually (possibly have to be) built on the 'vfat' filesystem. Knoppix DVDs are generally 4.7G in size ... which is too big to fit on 'vfat'. So I created a second partition on the USB stick that's ext2: note I load the module for 'ext2' and point the 'loopback' at the second partition.

Like the CD, the 32-bit Knoppix kernel on the DVD throws a panic on a 64-bit system. But the DVD also has a 64-bit kernel:

menuentry "Knoppix 7.7.1 DVD 64-bit" {
    insmod ext2
    set iso="/KNOPPIX_V7.7.1DVD-2016-10-22-EN.iso"
    loopback loop (hd0,msdos2)$iso
    linux (loop)/boot/isolinux/linux64 bootfrom=/mnt-iso/$iso lang=en apm=power-off nomce libata.force=noncq hpsa.hpsa_allow_any=1 loglevel=1
    initrd (loop)/boot/isolinux/minirt.gz
}

Some of Knoppix's utilities can be made to work:

menuentry "Knoppix memtest 7.7.1 DVD" {
    insmod ext2
    set iso="/KNOPPIX_V7.7.1DVD-2016-10-22-EN.iso"
    loopback loop (hd0,msdos2)$iso
    linux16 (loop)/boot/isolinux/memtest
}

This will then behave the same as the standalone entry for MemTest86+ given above.

I haven't yet convinced the Knoppix version of DOS to work:

menuentry "Knoppix DOS 7.7.1 DVD - ERROR" {
    insmod ext2
    set iso="/KNOPPIX_V7.7.1DVD-2016-10-22-EN.iso"
    loopback loop (hd0,msdos2)$iso
    linux16 (loop)/boot/isolinux/memdisk
    initrd (loop)/boot/isolinux/balder.img
}

This is currently failing with an "unaligned pointer 0x8 Aborted." error on both 32-bit and 64-bit.

Debian

This comes with a huge caveat: it can be made to work, but (as per Daniel's instructions) you'll need to get an initrd.gz from another source and include that with your ISO(s).

menuentry "Debian Jessie - 64bit Netinst+firmware - GOOD?" {
    set iso="/boot/iso/firmware-8.8.0-amd64-netinst.iso"
    loopback loop $iso
    linux (loop)/install.amd/vmlinuz iso-scan/ask_second_pass=true iso-scan/filename=$iso priority=low fromiso=/$iso --- quiet
    #initrd (loop)/install.amd/initrd.gz
    initrd /boot/iso/firmware-8.8.0-amd64-netinst.initrd.gz
}

menuentry "Debian Stretch RC3 DVD - 32bit - GOOD, ISO SEARCH" {
    set iso="/boot/iso/debian-stretch-DI-rc3-i386-DVD-1.iso"
    loopback loop $iso
    linux (loop)/install.386/vmlinuz iso-scan/ask_second_pass=true iso-scan/filename=$iso priority=low --- quiet
    # http://ftp.debian.org/debian/dists/stretch/main/installer-i386/current/images/hd-media/initrd.gz:
    initrd /boot/iso/debian-stretch-DI-rc3-i386.initrd.gz
}

I've retrieved the initrd.gz files and named them to match the ISOs that they go with. Note that they're found in /boot/iso/ rather than (loop)/install.386/ or (loop)/install.amd/ as you'd expect.

You're still not quite there, because once it starts to boot Debian won't find its ISO without a long search, and you may still (if you have multiple Debian ISOs on your USB stick as I do) have to tell it which ISO it needs to use.

Bunsen Labs Linux

Bunsen Labs Linux is the successor of the now defunct "CrunchBang Linux" (aka '#!"). It's based on Debian stable/jessie, so I'm using the Debian trick to make it boot ... with a Debian (not Bunsen) initrd for jessie. And it works, but I wouldn't be surprised if it broke the next time Debian recompiles their initrd.gz. See the entry for Debian above for how to get the correct file.

menuentry "Bunsen Labs i386 nonPAE - GOOD, CHOOSE LONG ISO SEARCH - CHANGED" {
    set iso="/boot/iso/bl-Deuterium-i386+NonPAE_20170429.iso"
    loopback loop $iso
    linux (loop)/install/vmlinuz iso-scan/filename=$iso
    initrd /boot/iso/firmware-8.8.0-i386-netinst.initrd.gz
}

Part way through the install process, it will probably tell you "The quick scan for installer ISO images, which looks only in common places, did not find an installer ISO image. It's possible that a more thorough search will find the ISO image, but it may take a long time. Do full disk search for installer ISO image?" The correct answer is "Yes," which will take a while as promised. But your troubles aren't yet over. Bunsen (like Debian) is too dumb to recognize its own ISO and will now expect you to choose its image from amongst the other Debian-style images you may have on the USB stick.

Slacko Puppy

menuentry 'Slacko (Puppy) 32-bit' {
    set isofile='/boot/iso/slacko-6.3.2-uefi.iso'
    loopback loop $isofile
    linux (loop)/vmlinuz pmedia=usbflash iso=$isofile
    initrd (loop)/initrd.gz
}

That looks simple, but there's a HUGE caveat on this one as well: when it boots, it will look for two files, 'slacko_6.3.2.sfs' and 'zdrv_slacko_6.3.2.sfs'. These files are on the root of the ISO, but Slacko Puppy isn't equipped to find them. So for this to work, as part of the setup you'll have to loop mount the ISO and copy those files from the ISO to the ROOT of the USB (the Debian files above we could get away with putting in the same subfolder as the ISO files: we can't do that this time). If you fail to copy 'zdrv_slacko_6.3.2.sfs', you'll have what appears to be a functional system, but with a non-working mouse: copy both files.

Tiny Core, Core, and Core Plus

menuentry "2017-05-20 Core 8.0" {
    set isofile='/boot/iso/Core-8.0.iso'
    loopback loop /boot/iso/Core-8.0.iso
    linux (loop)/boot/vmlinuz base showapps multivt vga=792 iso=/mnt/sda1/iso/Core8.0.iso
    initrd (loop)/boot/core.gz
}

Tiny Core Linux comes in several variants. "Core" (above) is the smallest and simplest, only booting to a prompt. The 'menuentry' above seems to work fine.

Both "Tiny Core Linux" and "Core Plus Linux" should boot to a GUI, but I haven't been able to get either to do so: both just boot to a prompt like Core:

menuentry "Tiny Core Linux 32-bit v8.0 - BOOT TO PROMPT" {
    insmod gzio
    insmod part_msdos
    insmod ext2
    insmod fat
    # gives us a pretty splash logo ... but still boots to prompt:
    set gfxpayload=keep
    set isofile='/boot/iso/TinyCore-8.0.iso'
    loopback loop /boot/iso/TinyCore-8.0.iso
    linux (loop)/boot/vmlinuz base showapps multivt vga=792 cde user=giles iso=/mnt/sda1/iso/TinyCore8.0.iso
    initrd (loop)/boot/core.gz
}

menuentry 'Core Plus Linux OpenBox 32-bit v8.0 - BOOT TO PROMPT' {
    set isofile='/boot/iso/CorePlus-8.0.iso'
    loopback loop $isofile
    linux (loop)/boot/vmlinuz loglevel=3 cde showapps desktop=openbox
    initrd (loop)/boot/core.gz
}

You can in fact install Tiny Core from a text prompt: http://www.parkytowers.me.uk/thin/Linux/CoreInstall.shtml is old, but that method still seems to work with version 8.0. I had hoped to install to (a) file(s) on the USB stick, but TinyCore thinks it needs its own partition.

Alpine Linux

menuentry 'Alpine x86_64 3.5.2 - BOOT AND FAIL' {
    set isofile='/boot/iso/alpine-standard-3.5.2-x86_64.iso'
    loopback loop $isofile
    set root=loop
    linux (loop)/boot/vmlinuz-grsec modloop=/boot/modloop-grsec modules=loop,squashfs,sd-mod,usb-storage
    initrd (loop)/boot/initramfs-grsec
}

This code block was courtesy of ArchWiki, and apparently it worked with the older version of Alpine that they were referencing. My suspicion is that Alpine stopped supporting booting from ISO. What you get now is "can't access tty ; job control turned off" and you get dumped at a prompt (32-bit or 64-bit versions).

Network Security Toolkit

This doesn't work, but I list it as a possible starting point:

menuentry 'Network Security Toolkit 24 64-bit - GOES TO EMERGENCY CONSOLE' {
    set isofile='/boot/iso/nst-24-7977.x86_64.iso'
    loopback loop $isofile
    linux (loop)/isolinux/vmlinuz0 initrd=initrd0.img root=CDLABEL=nst-24-7977.x86_64 rootfstype=auto ro rd.live.image rd.luks=0 rd.md=0 rd.dm=0 audit=0 systemd.unit=graphical.target nstrelocate=false
    initrd (loop)/isolinux/initrd0.img
}

It boots to an emergency console, but it does tell you where it's parked an extensive report/log of the boot problems. It may be fixable, I haven't taken the time to work on it yet.

GRUB's Limited Knowledge of the System

function cpu_props {
    echo "GRUB's ability to analyse processors is limited, we can only tell you:"
    if cpuid -p; then
        pae_assessment="PAE"
    else
        pae_assessment="NO PAE"
    fi
    if cpuid -l; then
        echo "64-bit processor, $pae_assessment"
    else
        echo "32-bit processor, $pae_assessment"
    fi
}

menuentry "Tell Me About This Machine's Processor" {
    cpu_props
    echo $"Press escape to return to the main menu"
    sleep --interruptible 9999
}

Of itself this isn't terribly useful - although it can at least tell you if a system is 32-bit or 64-bit, and if the system has PAE. But where this might be useful is to help GRUB decide whether or not to display a menuentry, such as not showing a 64-bit installer on a 32-bit system.

Showing Some Text

I got this from Rescatux's complex and well written GRUB configuration files:

menuentry "Tell Me About This USB Stick" {
    set oldpager="${pager}"
    set pager=1

    cat /boot/iso/notes/ABOUT.txt

    set pager="${oldpager}"
    unset oldpager
    echo $"Press escape to return to the main menu"
    sleep --interruptible 9999
}

This grabs the current state of the pager, then turns the pager on. Then it displays a text file and resets the state of the pager. Finally, it waits for the user to press a key to return to the menu.