The better way to make an Ubuntu 20.04 ISO that will boot on UEFI systems
Yesterday I wrote about how I made a 20.04 ISO that booted on UEFI systems. It was a messy process with some peculiar things that I didn't understand and places where I had to deviate from Debian's excellent documentation on Repacking a Debian ISO. In response to my entry, Thomas Schmitt (the author of xorriso) got in touch with me and very generously helped me figure out what was really going on. The short version is that I was confused and my problems were due to some underlying issues. So now I have had some learning experiences and I have a better way to do this.
First, I've learned that you don't want to extract ISO images
7z, however tempting and easy it seems. 7z has at least
two issues with ISO images; it will quietly add the El Torito boot images to
the extracted tree, in a new subdirectory called '
it doesn't extract symlinks (and probably not other Rock Ridge attributes).
The Ubuntu 20.04.1 amd64 live server image has some symlinks,
although their presence isn't essential.
The two reliable ways I know of to extract the 20.04.1 ISO image
bsdtar (part of the libarchive-tools package in Ubuntu)
and with xorriso itself. Bsdtar is easier to use but you probably
don't have it installed, while you need xorriso anyway and might
as well use it for this once you know how. So to unpack the ISO
into our scratch tree, you want:
xorriso -osirrox on -indev example.iso -extract / SCRATCH-TREE
(See the Debian wiki
for something you're going to want to do afterward to delete the
tree. Substitute whatever is the correct ISO name here in place of
As I discovered due to my conversation with Thomas Schmitt, it can be
important to re-extract the tree any time you think something funny
is going on. My second issue was that my tree's
had been quietly altered by something in a way that removed its FAT
signature and made UEFI systems refuse to recognize it (I suspect some
of my experimentation with
mkisofs did it, but I don't know for sure).
In a re-extracted tree with a pristine boot/grub/efi.img, the tree's efi.img was valid as an El Torito EFI boot image (and the isolinux.bin is exactly what was used for the original 20.04.1 ISO's El Torito BIOS boot image). So the command to rebuild an ISO that is bootable both as UEFI and BIOS, both as a DVD image and on a USB stick, is:
xorriso -as mkisofs -r \ -V 'Our Ubuntu 20.04 UEFI enabled' \ -o cslab_ubuntu_20.04.iso \ -isohybrid-mbr isohdpfx.bin \ -J -joliet-long \ -b isolinux/isolinux.bin -c isolinux/boot.cat \ -boot-load-size 4 -boot-info-table -no-emul-boot \ -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot \ -isohybrid-gpt-basdat \ SCRATCH-TREE
isohdpfx.bin file is generated following the instructions in
the Debian wiki page.
This entire command line is pretty much what the Debian wiki says
xorriso doesn't complain that some symlinks can't be represented
in a Joliet file
name tree, you haven't extracted the 20.04.1 ISO image exactly;
something has dropped the symlinks that should be there.
If you're modifying the ISO image to provide auto-installer data, you need to change both
boot/grub/grub.cfg. The necessary modifications are covered
in setting up a 20.04 ISO image to auto-install a server (for isolinux) and then yesterday's entry (for GRUB). You may also want to add various
additional files and pieces of data to the ISO, which can be done by
dropping them into the unpacked tree.
(It's also apparently possible to update the version of the installer that's in the ISO image, per here, but the make-edge-iso.sh and inject-subiquity-snap.sh scripts it points to in the subiquity repo are what I would call not trivial and so are beyond what I want to let monkey around in our ISO trees. I've already done enough damage without realizing it in my first attempts. I'll just wait for 20.04.2.)
On the whole this has been a learning experience about not questioning
my assumptions and re-checking my work. I have the entire process
of preparing the extracted ISO's scratch tree more or less automated,
so at any time I could have deleted the existing scratch tree,
re-extracted the ISO (even with
7z), and managed to build a working
UEFI booting ISO with boot/grub/efi.img. But I just assumed that
the tree was fine and hadn't been changed by anything, and I never
questioned various oddities until later (including the '
subdirectory, which wasn't named like anything else on the ISO