0

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
}
3
  • 2
    UEFI boots external drives from /EFI/Boot/bootx64.efi. With Windows that file is a copy of Windows .efi boot file. But with Ubuntu it is a copy of shimx64.efi. You can copy /EFI/Boot from any live installer. And you will need /boot/grub/grub.cfg and other files in /boot/grub to boot.
    – oldfred
    Jan 12, 2020 at 4:29
  • The ISO is a perfectly acceptable "EFI partition" in itself. I don't know what you are trying to do with efi.img...etc. You have the /EFI/Boot files (assuming the bootx64.efi is a copy of shimx64.efi), so do you have /EFI/ubuntu with a three line stub grub.cfg that just brings in the real grub.cfg from /boot/grub/grub.cfg? Thats all you should need. Your case wouldn't seem to need any /boot/efi mount point or an entry in fstab for it, and no other changes are necessary.
    – ubfan1
    Jan 13, 2020 at 17:13
  • @ubfan1, I have no idea what a stub grub.cfg is or where it should go. No, I don't have an EFI/ubuntu folder. What should be in the stub? Thanks for your help.
    – larry78723
    Jan 13, 2020 at 18:53

1 Answer 1

0

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 :

search.fs_uuid <UUID-of-the-Ubuntu-root> root hd?,gpt?   
set prefix=($root)'/boot/grub'  
configfile $prefix/grub.cfg  

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.

3
  • just to be sure I'm understanding what you're saying, all I should have to do is create the EFI/ubuntu folder and copy grub.cfg from /boot/grub to it? Does the grub.cfg (above) look correct?
    – larry78723
    Jan 13, 2020 at 23:21
  • ubfan1, thanks for trying but it didn't work. The original iso doesn't have a boot or EFI folder, so I added them and copied stuff from a mounted Ubuntu 18.04 iso. As a result, I might not have the correct stuff in them, resulting in a bad build of the EFI partition.
    – larry78723
    Jan 14, 2020 at 18:01
  • I just extracted the EFI partition and it has an EFI/BOOT folder but they are empty. I don't know where to go from here.
    – larry78723
    Jan 14, 2020 at 18:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .