如何创建一个EFI可引导的ISO文件,其中包含定制版本的Ubuntu?

我创建了一个自己的Ubuntu发行版,想要在我的MAC上通过USB启动它。
当使用来自Ubuntu网站的标准64位Ubuntu镜像时,它可以启动。然而,当我使用包含自己发行版的iso文件进行相同操作时,它却无法工作,并且似乎只支持传统引导方式。然而,这个操作系统有/sys/firmware/efi文件夹,所以我知道它支持EFI。我使用Relinux制作了这个iso文件。
我已经查看了这两个ISO文件之间的区别,并发现标准的Ubuntu中有一个包含grubx64.efi和BOOTx64.EFI的EFI/BOOT文件夹,还有一个在另一个文件夹中不存在的boot文件夹。我尝试将这两个文件夹(EFI和boot)复制到我的其他USB中,但是没有成功。
我的问题是:
- 如何将这两个文件夹添加到当前的iso文件中? - 如何制作一个支持EFI引导的发行版的iso文件?
3个回答

你需要制作一个双引导目录的ISO文件,以便可以通过EFI和MBR方式启动。标准的Ubuntu 14.04 x64 ISO文件可以实现这一点,但是没有提供制作适用于EFI系统的新14.04可引导ISO的指令。我能够整合出正确的步骤来创建这样的ISO文件。
以下是让你创建一个自定义的可以通过EFI和MBR引导的Ubuntu 14.04服务器ISO的指南。在EFI引导的系统上使用空白未初始化的磁盘(例如在Hyper-V中的新2代VM上),安装程序将自动启动,然后自动擦除磁盘并安装基本的ubuntu-server软件包和OpenSSH。这个设计用于自动配置使用LVM和自动分区的新系统的Ubuntu 14.04。如果你在已有的Linux系统上使用此ISO,则安装程序将在检测到现有磁盘时停止,并等待输入。如果你在非EFI系统上使用此ISO(例如第1代Hyper-V VM),则它将在图形化安装程序启动界面等待输入,然后才继续进行自动安装程序。
最终的结果是一个只包含ubuntu-server和openssh-server的基础Ubuntu Server安装。
下面是创建一个支持EFI引导的ISO的步骤:
1. 获取14.04 ISO文件:
wget http://releases.ubuntu.com/14.04/ubuntu-14.04-server-amd64.iso

将其安装并提取其内容到一个新文件夹中:
sudo mkdir -p ~/iso
sudo mount -o loop ubuntu-14.04-server-amd64.iso.iso ~/iso
sudo mkdir ~/ubuntu
sudo cp -rT ~/iso ~/ubuntu

进入我们将要进行工作的目录:
cd ~/ubuntu

将语言设置为英语:
sudo -i
echo en >/home/user/ubuntu/isolinux/lang
exit

创建一个preseed文件,使用LVM自动对磁盘进行分区,并利用所有可用空间。
sudo nano ~/ubuntu/ks.preseed

将文件内容替换为以下内容:
d-i partman-auto/method string lvm
d-i partman-auto-lvm/guided_size string max
d-i partman-auto/choose_recipe select atomic
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/confirm_write_new_label     boolean true
d-i partman/choose_partition            select  finish
d-i partman/confirm_nooverwrite         boolean true
d-i partman/confirm                     boolean true
d-i partman-auto/purge_lvm_from_device  boolean true
d-i partman-lvm/device_remove_lvm       boolean true
d-i partman-lvm/confirm                 boolean true
d-i partman-lvm/confirm_nooverwrite     boolean true
d-i partman-auto/init_automatically_partition       select      Guided - use entire disk and set up LVM
d-i partman/choose_partition                select      Finish partitioning and write changes to disk
d-i partman-auto-lvm/no_boot            boolean true
d-i partman-md/device_remove_md         boolean true
d-i partman-md/confirm                  boolean true
d-i partman-md/confirm_nooverwrite      boolean true

创建一个 kickstart 文件,在安装过程中配置 Ubuntu:(确保更改用户名部分,并使用加密密码)
sudo nano ~/ubuntu/ks.cfg

将文件内容替换为以下内容:
lang en_US
langsupport en_US
keyboard us
mouse
timezone America/Los_Angeles
rootpw --disabled
user USERNAME --fullname "USERNAME" --password "PASSWORD"
reboot
text
install
cdrom
auth  --useshadow  --enablemd5 
network --bootproto=dhcp --device=eth0
firewall --disabled 
skipx
%packages
@ ubuntu-server
openssh-server

编辑grub配置文件,这样当ISO执行EFI引导时,引导加载程序将使用正确的选项来使用我们的preseed和配置文件。
sudo nano ~/ubuntu/boot/grub/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/light-blue
set menu_color_highlight=light-blue/light-gray
set timeout=10
set default=0

menuentry "Automatically Install Ubuntu Server with Custom Config" {
    set gfxpayload=keep
    linux   /install/vmlinuz  file=/cdrom/preseed/ubuntu-server.seed quiet ks=cdrom:/ks.cfg preseed/file=/cdrom/ks.preseed --
    initrd  /install/initrd.gz
}
menuentry "OEM install (for manufacturers)" {
    set gfxpayload=keep
    linux   /install/vmlinuz  file=/cdrom/preseed/ubuntu-server.seed quiet oem-config/enable=true --
    initrd  /install/initrd.gz
}
menuentry "Multiple server install with MAAS" {
    set gfxpayload=keep
    linux   /install/vmlinuz  modules=maas-enlist-udeb vga=788 initrd=/install/initrd.gz quiet --
    initrd  /install/initrd.gz
}
menuentry "Check disc for defects" {
    set gfxpayload=keep
    linux   /install/vmlinuz  MENU=/bin/cdrom-checker-menu quiet --
    initrd  /install/initrd.gz
}
menuentry "Rescue a broken system" {
    set gfxpayload=keep
    linux   /install/vmlinuz  rescue/enable=true --
    initrd  /install/initrd.gz
}

编辑 isolinux 引导菜单以进行非 EFI 引导(MBR 引导),使用自定义配置和自定义 preseed。
sudo nano ~/ubuntu/isolinux/txt.cfg

将文件内容替换为以下内容:
default install
label install
  menu label ^Install Ubuntu Server with Custom Config
  kernel /install/vmlinuz
  append file=/cdrom/preseed/ubuntu-server.seed initrd=/install/initrd.gz ks=cdrom:/ks.cfg preseed/file=/cdrom/ks.preseed --
label cloud
  menu label ^Multiple server install with MAAS
  kernel /install/vmlinuz
  append   modules=maas-enlist-udeb vga=788 initrd=/install/initrd.gz quiet --
label check
  menu label ^Check disc for defects
  kernel /install/vmlinuz
  append   MENU=/bin/cdrom-checker-menu vga=788 initrd=/install/initrd.gz quiet --
label memtest
  menu label Test ^memory
  kernel /install/mt86plus
label hd
  menu label ^Boot from first hard disk
  localboot 0x80

创建ISO:
此命令是对http://petersmithphotog.no-ip.biz/wiki/index.php/Unattended_Install中显示的命令进行了修改。这些说明不适用于Ubuntu 14.04,因为它们指向了错误的位置来获取efi.img文件(应该在ISO的./boot/grub/目录下)。
sudo mkisofs -U -A "Custom1404" -V "Custom1404" -volset "Custom1404" -J -joliet-long -r -v -T -o ../Custom1404.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot .

验证ISO是否具有正确的引导目录样式:

你从Ubuntu下载的原始ISO:

dumpet -i ~/ubuntu-14.04-server-amd64.iso 

输出:

Validation Entry:
    Header Indicator: 0x01 (Validation Entry)
    PlatformId: 0x00 (80x86)
    ID: ""
    Checksum: 0x55aa
    Key bytes: 0x55aa
Boot Catalog Default Entry:
    Entry is bootable
    Boot Media emulation type: no emulation
    Media load segment: 0x0 (0000:7c00)
    System type: 0 (0x00)
    Load Sectors: 4 (0x0004)
    Load LBA: 8446 (0x000020fe)
Section Header Entry:
    Header Indicator: 0x91 (Final Section Header Entry)
    PlatformId: 0xef (EFI)
    Section Entries: 1
    ID: ""
Boot Catalog Section Entry:
    Entry is bootable
    Boot Media emulation type: no emulation
    Media load address: 0 (0x0000)
    System type: 0 (0x00)
    Load Sectors: 4672 (0x1240)
    Load LBA: 24754 (0x000060b2)

你创建的新ISO:
dumpet -i ~/Custom1404.iso 

输出:

Validation Entry:
    Header Indicator: 0x01 (Validation Entry)
    PlatformId: 0x00 (80x86)
    ID: ""
    Checksum: 0x55aa
    Key bytes: 0x55aa
Boot Catalog Default Entry:
    Entry is bootable
    Boot Media emulation type: no emulation
    Media load segment: 0x0 (0000:7c00)
    System type: 0 (0x00)
    Load Sectors: 4 (0x0004)
    Load LBA: 3100 (0x00000c1c)
Section Header Entry:
    Header Indicator: 0x91 (Final Section Header Entry)
    PlatformId: 0xef (EFI)
    Section Entries: 1
    ID: ""
Boot Catalog Section Entry:
    Entry is bootable
    Boot Media emulation type: no emulation
    Media load address: 0 (0x0000)
    System type: 0 (0x00)
    Load Sectors: 4672 (0x1240)
    Load LBA: 1932 (0x0000078c)

你可以将这个输出与使用如何创建完全无人值守安装Ubuntu的指南构建的ISO的输出进行比较:(他们创建的是仅包含MBR的ISO,而不是双启动目录的ISO)
sudo mkisofs -D -r -V "non-efi-ubuntu" -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o ../non-efi-ubuntu.iso .

获取ISO信息:
dumpet -i ~/non-efi-ubuntu.iso 

输出:

Validation Entry:
    Header Indicator: 0x01 (Validation Entry)
    PlatformId: 0x00 (80x86)
    ID: ""
    Checksum: 0x55aa
    Key bytes: 0x55aa
Boot Catalog Default Entry:
    Entry is bootable
    Boot Media emulation type: no emulation
    Media load segment: 0x0 (0000:7c00)
    System type: 0 (0x00)
    Load Sectors: 4 (0x0004)
    Load LBA: 1925 (0x00000785)

虽然这是一个非常详细的回答,但它似乎不仅仅是创建可引导的EFI ISO那么简单。预置和kickstart是否必要?如果是的话,为什么不只使用一个呢?据我所知,预置可以覆盖kickstart所做的一切。 - muru
2它不仅可以创建一个EFI可引导的ISO文件。通过从这些说明中删除kickstart和preseed选项,您可以创建一个标准的Ubuntu 14.04 ISO文件。具体的更改已在答案中注明。 - anothermh
1那么我请求您只保留相关部分在这里,因为您已经在未经监控的安装问题上得到了其他所有答案。 - muru
2是的!我一直在四处寻找一种从自定义文件夹创建EFI可引导ISO的方法..很高兴你把所有东西都放在这里! - Alex R
1这在虚拟机中运行得很好,但是当我将它复制到USB驱动器上时,无法像使用原始的Ubuntu镜像那样启动。 - HarlemSquirrel
有人尝试过使用virt-manager中的图像吗? - gudge
我不得不添加d-i preseed/early_command字符串umount /media - Peter
2@HarlemSquirrel,要从USB闪存驱动器安装,您只需要再执行一步操作,将ISO文件转换为可引导的USB驱动器格式:# isohybrid path/to/image.iso - jjnebeker
对于使用UEFI安装,您可以将ISO内容复制到一个FAT32格式的USB闪存驱动器上。然后您可以编辑文件。请参考:https://askubuntu.com/questions/395879/how-to-create-uefi-only-bootable-usb-live-media/395880#395880 - phiphi

启用UEFI的USB驱动器

如果您想要从USB介质进行安装,您无需先创建自定义ISO。

创建仅支持UEFI引导的USB实时媒体非常简单。只需将文件复制到格式为FAT32的USB驱动器中。就这样! 它将被识别为有效的UEFI引导介质。

然后,您可以直接在USB驱动器上修改文件。

来源和详细信息:如何创建仅支持UEFI引导的USB实时媒体?


对我来说,最好的方法是:
1)创建系统备份的Live ISO。
sudo apt-get install systemback
sudo apt-get install live-boot
sudo apt-get autoremove --purge casper

2) 以以下方式向ISO添加UEFI分区:
cd /home
cat `ls -1 -t syst*.iso|head -1` efi.img >/tmp/live.iso
echo -e "n\np\n2\n\n\nt\n2\nef\nw\n"|fdisk /tmp/live.iso

3) 将 ISO 复制到媒体(在本例中是我的 /dev/sdb 上的闪存驱动器)。
pv /tmp/live.iso | dd of=/dev/sdb conv=notrunc,noerror