== Making an Ubuntu 20.04 ISO that will boot on UEFI systems As part of [[our overall install process UbuntuOurInstallSystem]], for years we've used customized Ubuntu server install images (ie, ISOs, often burned on to actual DVDs) that were set up with preseed files for the Debian installer and a few other things we wanted on our servers from the start. These ISOs have been built in the traditional way with [[_mkisofs_ https://linux.die.net/man/8/mkisofs]] and so booted with [[_isolinux_ https://wiki.syslinux.org/wiki/index.php?title=ISOLINUX]]. This was fine for a long time because pretty much all of our servers used traditional MBR BIOS booting, which is what ISOs use isolinux for. However, for or reasons outside the scope of this entry, today we wanted to make our 20.04 ISO image also boot on systems using UEFI boot. This turned out to be more complicated than I expected. (For basic background on this, see my earlier entry on [[setting up a 20.04 ISO image to auto-install a server Ubuntu2004ISOAutoinst]].) First, as my co-workers had already discovered long ago, Linux ISOs do UEFI booting using GRUB2, not isolinux, which means that you need to customize the grub.cfg file in order to add the special command line parameters to tell the installer about [[your 20.04 installer data Ubuntu2004AutoinstFormat]]. We provide the installer data in the ISO image, which means that our kernel command line arguments contain a ';'. In GRUB2, I discovered that this must be quoted: .pn prewrap on > menuentry "..." { > [...] > linux /casper/vmlinuz quiet "ds=nocloud;s=/cdrom/cslab/inst/" --- > [...] > } (I advise you to modify the title of the menu entries in the ISO's grub.cfg so that you know it's using your modified version. It's a useful reassurance.) If you don't do this quoting, all the kernel (and the installer) see is a '_ds=nocloud_' argument. Your installer data will be ignored (despite being on the ISO image) and you may get confused about what's wrong. The way ISOs are made bootable is that they have at least one [[El Torito https://en.wikipedia.org/wiki/ISO_9660#El_Torito]] boot section (see also [[the OsDev Wiki https://wiki.osdev.org/El-Torito]]). A conventional BIOS bootable ISO has one section; one that can also be booted through UEFI has a second one that is more intricate. You can examine various information about El Torito boot sections with [[_dumpet_ https://github.com/rhboot/dumpet]], which is in the standard Ubuntu repositories. In theory I believe _mkisofs_ can be used to add a suitable extra ET boot section. In practice, everyone has switched to building ISO images with [[_xorriso_ https://www.gnu.org/software/xorriso/]], for good reason. The easiest to follow guide on using _xorriso_ for this is the Debian Wiki page on [[Repacking a Debian ISO https://wiki.debian.org/RepackBootableISO]], which not only has plenty of examples but goes the extra distance to explain what the many _xorriso_ arguments mean and do (and why they matter). This is extremely useful since _xorriso_ has a large and complicated manpage and other documentation. ~~Important update~~: The details of much of the rest of this entry turns out to not be right, because I had a corrupted ISO tree with altered files. For a better procedure and more details, see [[The better way to make an Ubuntu 20.04 ISO that will boot on UEFI systems Ubuntu2004ISOWithUEFI-2]]. The broad overview of UEFI requiring a GRUB2 EFI image is accurate, though. However, Ubuntu has a surprise for us (of course). UEFI bootable Linux ISOs need a GRUB2 EFI image that is embedded into the ISO. Many examples, including [[the Debian wiki page https://wiki.debian.org/RepackBootableISO]], get this image from a file in the ISO image called _boot/grub/efi.img_. The Ubuntu 20.04.1 ISO image has such a file, but it is not actually the correct file to use. If you build an ISO using this efi.img as the El Torito EFI boot image, it will fail on at least some UEFI systems. The file you actually want to use turns out to be '_[BOOT]/2-Boot-NoEmul.img_' in the ISO image. (Although the 20.04.1 ISO image's _isolinux/isolinux.bin_ works fine as the El Torito BIOS boot image, it also appears to not be what the original 20.04.1 ISO was built with. The authentic thing seems to be '_[BOOT]/1-Boot-NoEmul.img_'. I'm just thankful that Ubuntu put both in the ISO image, even if it sort of hid them.) ~~Update~~: These '_[BOOT]_' files aren't in the normal ISO image itself, but are added by _7z_ (likely from the El Torito boot sections) when it extracts the ISO image into a directory tree for me. The _isolinux.bin_ difference is from a boot info table that contains the block offsets of _isolinux.bin_ in the ISO. The _efi.img_ differences are currently more mysterious. The resulting _xorriso_ command line I'm using right now is more or less: > 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]/2-Boot-NoEmul.img' -no-emul-boot \ > -isohybrid-gpt-basdat \ > SCRATCH-DIRECTORY (assuming that _SCRATCH-DIRECTORY_ is your unpacked and modified version of the 20.04.1 ISO image, and _isohdpfx.bin_ is generated following the instructions in [[the Debian wiki page]].) The ISO created through this definitely boots in VMWare in both UEFI and BIOS mode (and installs afterward). I haven't tried it in UEFI mode on real hardware yet and probably won't for a while. PS: If you use the Debian wiki's [[suggested _xorriso_ command line https://wiki.debian.org/RepackBootableISO#What_to_do_if_no_file_.2F.disk.2Fmkisofs_exists]] to analyze the 20.04.1 ISO image, it will claim that the El Torito EFI boot image is 'boot/grub/efi.img'. This is definitely not the case, which you can verify by using _dumpet_ to extract both of the actual boot images from the ISO and then _cmp_ to see what they match up with.