为仅基于 BIOS 的 Ubuntu 18.04 自定义 iso 添加 UEFI 启动功能

为仅基于 BIOS 的 Ubuntu 18.04 自定义 iso 添加 UEFI 启动功能

我正在尝试将 UEFI 启动功能添加到仅基于 BIOS 的 Ubuntu 18.04 自定义 iso。到目前为止,我发现的所有方法都需要一个 efi.img 文件,而该文件不存在于 iso 中。我可以在完整安装的 Ubuntu 18.04 之外使用该文件吗?如果是,我需要编辑它吗?如果不是,我该如何构建 efi.img 文件?

自定义 iso 旨在从 USB 运行,而不是安装。它还旨在分发给新的 Linux 用户。将 UEFI 功能添加到 USB 而不是 iso 并不是我们正在寻找的解决方案。

这是我用来构建 fat 分区的脚本。它在包含提取的 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."

这是我用来构建 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"

有人发现代码有问题吗?我真的希望用不同的眼光来看待这个问题,因为我觉得我已经“只见树木不见森林”了。

编辑:boot/grub 和 EFI/BOOT 的内容如下

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

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
}

答案1

我认为您只需将引导加载程序 shimx64.efi 和 grubx64.efi 以及 grub 配置文件添加到 /EFI 目录的子目录中即可启用 UEFI 启动功能。请参阅标准 Ubuntu ISO 以了解相同的设置。您已经为 /EFI/Boot 设置了可移动媒体 UEFI,其中包含 grubx64.efi,并且 shimx64.efi 已重命名为 bootx64.efi。您所需要的只是 /EFI/ubuntu 中的 grub.cfg。在已安装的系统上,此 grub.cfg 只是一个三行存根,它从 /boot/grub/grub.cfg 复制维护的 grub.cfg,但在您的情况下,我认为您不会更新更改 /boot/grub/grub.cfg 的内核,因此只需将 /boot/grub/grub.cfg 文件的副本放在那里即可。仅供参考,存根 grub 看起来像(您的 UUID 和硬盘编号 x 和分区号:

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

存根将复制到安装维护的 grub.cfg 副本中,因此完整的 grub 文件不会发生变化(在您的情况下没有内核更新)就可以了。我开始看到将 grub.cfg 放入 /EFI/Boot 的建议,但过去却不行,grub 只会在 /EFI/ubuntu 中查找 grub.cfg。


是的,设置起来其实很简单。如果您为自己的案例取了正确的名称,那么 grub.cfg 看起来就没问题:initrd 而不是 initrd.lz,vmlinuz 而不是 vmlinuz.efi(如标准 Xenial Ubuntu ISO 所用)。

相关内容