如何配置 grub 从 exfat 分区启动 ISO 映像?

如何配置 grub 从 exfat 分区启动 ISO 映像?

由于 Ubuntu LTS 22.04 桌面映像的文件大小增加,Linux 笔式驱动器创建者很快就会感受到痛苦,因为他们意识到单个分区、FAT32 驱动器无法满足想要启动这个(和其他)更大 ISO 的用户的需求。

EFI 至少需要两个分区,因为 EFI严格且仅支持 FAT32

因此,我将 USB 格式化为具有用于 EFI 的 FAT32 分区和用于存储和其他所有内容的 EXFAT 分区,如下所示:

  • (usb)E:/EFI/- FAT32 分区上的 EFI 文件夹
  • (usb)B:/boot/grub/-grub安装
  • (usb)B:/images/- iso 文件夹包含kali-linux-2023.3-live-amd64.isoubuntu-22.04.3-desktop-amd64.iso

我决定将 grub 安装在与图像相同的分区上,认为这可能会有所帮助,但我也尝试将 grub 安装在与 EFI 位置相邻的 FAT32 分区上(E:/boot/grub/实际上是这样),但失败了,出现了同样的错误。

从 USB 启动时,grub 加载正常。我看到出现了 2 个菜单选项,并且自定义 grub 主题内容全部显示出来,但无论是启动 Kali 还是 Ubuntu,所发生的一切就是正确的启动画面和徽标出现一秒钟,然后我就陷入了一个initramfs(busybox?) shell 中,它抱怨说:

Could not find the ISO /images/ubuntu-22.04.3-desktop-amd64.iso

这是完整的 grub 配置(主题内容并不是真正需要的,但为了清楚起见在这里发布):

if [ -s $prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi

font=unicode

if loadfont $font ; then
  set locale_dir=$prefix/locale
  set lang=en_IN
fi

set gfxmode=auto
set gfxpayload=keep
set timeout=60
set default=0
set root="(hd0,msdos1)"

insmod all_video
insmod gfxterm
# insmod exfat
insmod part_msdos
insmod part_gpt
insmod regexp
insmod gettext
# insmod ext2
# insmod loopback
# insmod iso9660
insmod gfxmenu
insmod jpeg
insmod png

terminal_output gfxterm

loadfont ($root)/boot/grub/themes/stylish/dejavu_32.pf2
loadfont ($root)/boot/grub/themes/stylish/dejavu_sans_12.pf2
loadfont ($root)/boot/grub/themes/stylish/dejavu_sans_14.pf2
loadfont ($root)/boot/grub/themes/stylish/dejavu_sans_16.pf2
loadfont ($root)/boot/grub/themes/stylish/dejavu_sans_24.pf2
loadfont ($root)/boot/grub/themes/stylish/dejavu_sans_48.pf2
loadfont ($root)/boot/grub/themes/stylish/terminus-12.pf2
loadfont ($root)/boot/grub/themes/stylish/terminus-14.pf2
loadfont ($root)/boot/grub/themes/stylish/terminus-16.pf2
loadfont ($root)/boot/grub/themes/stylish/terminus-18.pf2

set theme=($root)/boot/grub/themes/stylish/theme.txt
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray

export theme

# Ubuntu
menuentry "Ubuntu 22.04 Desktop" --class ubuntu --class linux {
    set root="(hd0,msdos1)"
    set isofile="/images/ubuntu-22.04.3-desktop-amd64.iso"
    # rmmod tpm
    insmod exfat
    loopback loop $isofile
    linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=${isofile} quiet splash toram tpm_tis.interrupts=0
    initrd (loop)/casper/initrd
}

# Kali Linux
menuentry "Kali Linux Live ISO" --class kali --class linux {
    set root='(hd0,msdos1)'
    set isofile="/images/kali-linux-2023.3-live-amd64.iso"
    rmmod tpm
    insmod ext2
    insmod loopback
    insmod iso9660
    loopback loop $isofile
    linux (loop)/live/vmlinuz boot=live components quiet splash toram noeject findiso=${isofile} tpm_tis.interrupts=0
    initrd (loop)/live/initrd.img
}

grub 文档非常清楚直接启动 ISO 是可能的(因为它已经存在很长一段时间了)——我只是无法弄清楚这里出了什么问题。

要明确的是 - 我不想要一个可以格式化 USB 并自动完成所有操作的工具或解决方案 - 我问的是我需要对文件进行哪些更改grub.cfg才能获得预先存在的、可以正常工作的 grub USB 安装来启动位于同一 USB 驱动器上的 ISO 映像。

我已经尝试过的事情:

  • 删除所有主题内容(以防万一)
  • 尽早安装 grub 模块(注释掉的行所在的位置),而不是在菜单项内
  • 在 EFI 文件夹旁边的 FAT32 分区上安装 grub
  • 删除 iso 文件路径周围的引号
  • 哭着吃早餐
  • 使用完全不同的 USB 记忆棒
  • 使用不同的计算机/主机

我很确定这不是硬件问题 - 这是我未正确编程 grub 的问题,但我很困惑,如能得到任何帮助我将非常感谢。

额外的

我认为我也有同样的问题就像这个人,我读完了这个答案但在那里找不到我尚未阅读过或在互联网其他地方找到的信息。

似乎有一个暗示pendrivelinux 上的这篇过时的帖子- 引人注目的一段话:

...grub 可以使用此方法从 exFAT 文件系统读取,因为它包含 exFAT 驱动程序模块。但是,要真正能够通过回送从存储在 exFAT 分区上的 Live ISO 启动,需要发行版也包含驱动程序,并且 exFAT 分区在启动期间自动挂载。否则,一旦启动过程被移交,将不再找到 ISO 的路径。当发生这种情况时,您可能会被放入 BusyBox shell。

这可能是正在发生的事情,但有那么多的“ubuntu 闪存驱动器指南”似乎使用这个确切的方法,我想我只是假设它会起作用,但事实并非如此吗?

答案1

问题确实出在文件系统上。我删除了 exfat 分区并重新格式化了 USB 驱动器,如下所示:

  • (usb, FAT32) E:/EFI/- EFI 文件夹
  • (usb, FAT32) E:/boot/grub/- grub 安装,移回 FAT32 分区
  • (usb, EXT4) B:/images/- ext4 分区(原为 exfat)
  • (usb, EXFAT) S:/- 减小了 exfat 分区的大小,适合 Linux 和 Windows 友好的文件存储

棘手的部分是将 Windows 机器上的图像传输到 Windows 没有内置支持的 ext4 分区上,但一旦我这样做并更新菜单项,我就可以启动 Kali 和 Ubuntu。

# Ubuntu
menuentry "Ubuntu 22.04 Desktop" --class ubuntu --class linux {
    set root="(hd0,msdos1)"
    set isofile="/images/ubuntu-22.04.3-desktop-amd64.iso"
    insmod ext2
    loopback loop $isofile
    linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=${isofile} quiet splash toram tpm_tis.interrupts=0
    initrd (loop)/casper/initrd
}

# Kali Linux
menuentry "Kali Linux Live ISO" --class kali --class linux {
    set root='(hd0,msdos1)'
    set isofile="/images/kali-linux-2023.3-live-amd64.iso"
    insmod ext2
    loopback loop $isofile
    linux (loop)/live/vmlinuz boot=live components quiet splash toram noeject findiso=${isofile} tpm_tis.interrupts=0
    initrd (loop)/live/initrd.img
}

相关内容