I am trying to add UEFI boot capability to a BIOS only Ubuntu 18.04 based custom iso. All the methods I've found so far require an efi.img file which isn't present in the iso. Can I use the file out of a full install Ubuntu 18.04? If yes, do I need to edit it? If not, how can I construct an efi.img file?
The custom iso is designed to run from a USB, not installed. It is also intended for distribution to new Linux users. Adding UEFI capabilities to the USB rather than the iso isn't the solution we're looking.
This is the script that I used to build the fat partition. It is run in the folder containing the extracted iso:
#! /bin/sh
BOOT_IMG_DATA="$PWD"
BOOT_IMG=efi.img
#Ensure needed folders exist
if [ ! -d "$BOOT_IMG_DATA"/efi/boot ]; then
mkdir -p "$BOOT_IMG_DATA"/efi/boot
fi
if [ ! -d "$BOOT_IMG_DATA"/boot/grub ]; then
mkdir -p "$BOOT_IMG_DATA"/boot/grub
fi
chmod -R +rw "$BOOT_IMG_DATA"/boot/grub
chmod -R +rw "$BOOT_IMG_DATA"/efi/boot
# Create the 64-bit EFI GRUB binary (bootx64.efi) and the El-Torito boot
# image (efiboot.img) that goes in the /isolinux directory for booting on
# UEFI systems.
# First, build bootx64.efi, which will be installed here in /EFI/BOOT:
grub-mkimage --format=x86_64-efi --output=bootx64.efi --config=grub.cfg --compression=xz --prefix=/EFI/BOOT part_gpt part_msdos fat ext2 hfs hfsplus iso9660 udf ufs1 ufs2 zfs chain linux boot appleldr ahci configfile normal regexp minicmd reboot halt search search_fs_file search_fs_uuid search_label gfxterm gfxmenu efi_gop efi_uga all_video loadbios gzio echo true probe loadenv bitmap_scale font cat help ls png jpeg tga test at_keyboard usb_keyboard
# Then, create a FAT formatted image that contains bootx64.efi in the
# /EFI/BOOT directory. This is used to bootstrap GRUB from the ISO image.
dd if=/dev/zero of=efiboot.img bs=1K count=1440
# Format the image as FAT12:
mkdosfs -F 12 efiboot.img
# Create a temporary mount point:
MOUNTPOINT=$(mktemp -d)
# Mount the image there:
mount -o loop efiboot.img $MOUNTPOINT
# Copy the GRUB binary to /EFI/BOOT:
mkdir -p $MOUNTPOINT/EFI/BOOT
cp -a bootx64.efi -s $MOUNTPOINT/EFI/BOOT
# Unmount and clean up:
umount $MOUNTPOINT
rmdir $MOUNTPOINT
# Move the efiboot.img to isolinux:
mv efiboot.img isolinux
mv bootx64.efi efi/boot
echo
echo "Done building /EFI/BOOT/bootx64.efi and /isolinux/efiboot.img."
This is the script I use to build the iso:
#!/bin/bash
# The example names get mapped to their roles here
orig_iso="$HOME"/foxclone/foxclone025-01.iso
new_iso="$HOME"/foxclone/foxclone025-02.iso
new_files="$PWD"
mbr_template=isohdpfx.bin
# Extract MBR template file to disk
dd if="$orig_iso" bs=1 count=432 of="$mbr_template"
# Create the new ISO image
xorriso -as mkisofs \
-U \
-allow-lowercase \
-r -V 'foxclone025-02' \
-o "$new_iso" \
-J -J -joliet-long \
-isohybrid-mbr "$mbr_template" \
-c isolinux/boot.cat \
-b isolinux/isolinux.bin \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-eltorito-alt-boot \
-e isolinux/efiboot.img \
-no-emul-boot \
-isohybrid-gpt-basdat \
"$new_files"
Does anyone see a problem in the code? I really appreciate a different set of eyes looking at this as I think I've gotten "too close to the forest to see the trees".
EDIT: Contents of boot/grub and EFI/BOOT follows
larry@larry-Satellite-C55-A:~/foxclone/iso3$ ls -l boot/grub
total 2492
-rw------- 1 larry larry 2523136 Jul 31 01:33 efi.img
-rw------- 1 larry larry 5004 Mar 18 2019 font.pf2
-rw------- 1 larry larry 941 Aug 5 15:28 grub.cfg
-rw------- 1 larry larry 604 Aug 5 15:28 loopback.cfg
drwxr-xr-x 2 larry larry 12288 Jan 13 09:20 x86_64-efi
larry@larry-Satellite-C55-A:~/foxclone/iso3$ ls -l EFI/BOOT
total 2424
-rw------- 1 larry larry 1334816 Aug 5 15:28 BOOTx64.EFI
-rw------- 1 larry larry 1146744 Aug 5 15:28 grubx64.efi
Contents of grub.cfg
if loadfont /boot/grub/font.pf2 ; then
set gfxmode=auto
insmod efi_gop
insmod efi_uga
insmod gfxterm
terminal_output gfxterm
fi
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
set timeout=5
menuentry "Foxclone" {
set gfxpayload=keep
linux /casper/vmlinuz boot=casper quiet splash ---
initrd /casper/initrd
}
I think you will enable UEFI boot capability by simply adding the bootloaders shimx64.efi and grubx64.efi and the grub configuration file to subdirectories of the /EFI directory. See a standard Ubuntu ISO for the the same setup. You already have the removable media UEFI setup for /EFI/Boot, with grubx64.efi present, and shimx64.efi there but renamed to bootx64.efi. All you need is a grub.cfg in /EFI/ubuntu. On an installed system, this grub.cfg is just a three line stub, which copies the maintained grub.cfg from /boot/grub/grub.cfg, but in your case, I don't think you will be updating kernels which change the /boot/grub/grub.cfg, so just put a copy of the /boot/grub/grub.cfg file there. FYI, the stub grub looks like (your UUID and hd number x and partition number :
The stub will be copying in the install's maintained copy of grub.cfg, so a full grub file which does not change (no kernel updates in your case) is fine. I have started seeing recommendations that putting grub.cfg into /EFI/Boot works now, but in the past that did not, grub only looked in /EFI/ubuntu for the grub.cfg.
Right, it's actually pretty simple to set up. The grub.cfg looks OK if you got the names right for your case: initrd and not initrd.lz and vmlinuz and not vmlinuz.efi like the standard Xenial Ubuntu ISO uses.