从 rootfs linux 文件创建可启动 iso 文件

从 rootfs linux 文件创建可启动 iso 文件

我想从典型的 Linux 分发文件制作可启动的 iso 文件。我尝试制作 grub 引导加载程序,首先我使用 grub.cfg 创建模板grub-mkconfig,并在开始时添加了此配置:

set default=0
set timeout=5

menuentry "LinuxTest" {
    set root=(hd0)
    linux /boot/bzImage root=/dev/sda1
}

然后我用了grub-mkrescue -o /path/to/file.iso /path/to/linux/files

但是当我尝试启动它时,它显示“错误:未知文件系统”

我做错了什么/没有做什么来让它发挥作用?

Linux 文件

grub-cli 中的 ls

答案1

复制第二张图片中的文本:

grub> ls
(proc) (hd0) (cd) (cd,apple4) (cd,apple3) (cd,apple2) (cd,apple1) (cd,gpt4) (cd,gpt3) (cd,gpt2) (cd,gpt1)
grub> _

UEFI 不是 BIOS:系统不会始终将当前启动介质安排为(hd0)GRUB。在这种情况下,启动介质看起来可能已被识别为(cd).

您非常简单的 GRUB 配置片段尝试读取(hd0)为单个未分区设备,但它看起来像是一个空的未分区磁盘,或者可能是 GRUB 的 GPT 分区检测模块无法识别的某种分区方式。

您的 GRUB 配置片段甚至不是自洽的:假设 Linux 内核将视为(hd0)/dev/sda无论如何都不能保证!),这set root=(hd0)表明将有一个/dev/sda包含路径的文件系统/boot/bzImage

另一方面,Linux 内核引导参数root=/dev/sda1建议/dev/sda进行分区,并且根文件系统将位于第一个分区上。

要么/dev/sda是未分区的并且仅包含覆盖整个磁盘/映像的单个文件系统,要么是已分区的并且/dev/sda1是第一个分区;它们不能同时为真。

为了获得教育体验,我建议您尝试将 生成的 ISO 映像附加grub-mkrescue到循环设备,并调查在以下位置检测到的任何分区的内容:

ls /dev/loop*
sudo losetup -P --show -f /path/to/file.iso
ls /dev/loop*          # you might see more than one new device!
file -s /dev/loop*     # to identify the filesystem types within

losetup命令将输出/dev/loopX样式循环设备名称,但它实际上也会为其中包含的任何分区创建循环设备。记下 X 位置上的数字,并将其替换为X以下任意命令中的 :

尝试一下fdisk -l /dev/loopX:看似单个的 ISO 文件实际上包含一个有效的 GPT 分区表,它看起来像这样(分区大小可能不同):

# fdisk -l /dev/loop0
Disk /dev/loop0: 13,22 MiB, 13867008 bytes, 27084 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 7FB1CA87-86D8-4C32-A49D-F5CEB184C045

Device       Start   End Sectors  Size Type
/dev/loop0p1    64   251     188   94K Microsoft basic data
/dev/loop0p2   252  6011    5760  2,8M EFI System
/dev/loop0p3  6012 26435   20424   10M Apple HFS/HFS+
/dev/loop0p4 26436 27035     600  300K Microsoft basic data

这是因为它不仅仅是一个普通的旧 ISO-9660 图像,而是一个混合 ISO-9660/硬盘映像。这是与 Linux 相关的 ISO 映像中非常常见的技巧。

如果您使用fdisk /dev/loopX,然后使用i命令fdisk来获取有关分区的更多信息,您将看到“Microsoft 基本数据”分区分别被命名为Gap0Gap1,这表明它们只是为了隐藏 ISO-9660 文件系统元数据等else 需要从“硬盘映像”视图中隐藏。

EFI 系统分区包含 FAT 系列的文件系统,并且仅包含一个文件:efi/boot/bootx64.efi.

Apple HFS+ 分区包含 的副本/path/to/linux/files,其中还包含一些额外的文件:一个boot/grub/包含完整 GRUB 模块集的目录层次结构,以及一个包含和 的System/Library/CoreServices/目录,前者与EFI 系统分区上的文件相同。boot.efiSystemVersion.plistbootx64.efi

bootx64.efi/是boot.efi适用于 64 位 UEFI 架构的 GRUB,内置支持 MBR、GPT 和旧版 macOS 分区,并通过嵌入式配置加载更多模块,以在可能的情况下支持甚至奇异的分区类型。 (基本上,boot/grub/x86_64-efi/part_*.mod如果可以的话,它被配置为按字母顺序加载所有GRUB 模块文件。)

通过isoinfo -i /path/to/file.iso,我们可以发现grub-mkrescue将 ISO-9660 文件系统标签设置为ISOIMAGE,因此至少,您应该像这样设置 GRUB 配置片段:

set default=0
set timeout=5

menuentry "LinuxTest" {
    search --label --set root "ISOIMAGE"
    linux /bzImage root=/dev/sda
}

这应该使 GRUB 按标签搜索文件系统,并使其成为任何后续文件路径引用的新根。

从你的第一张图片中我看到该bzImage文件不在/boot目录中,而是在 ISO-9660 文件系统的根目录中,因此路径名也需要修复。

最后,内核的根文件系统参数可能很困难。由于您没有使用 initramfs,因此如何指定根文件系统有一些限制:您只能使用/dev/*名称、PARTUUID=语法或PARTLABEL=语法,而不能使用文件系统标签。

您的根文件系统内容可以作为整个磁盘设备上的 ISO-9660 文件系统进行访问,不幸的是,它不包括PARTUUID=PARTLABEL=

访问它的另一种方法是使用第三个分区上的 HFS+ 文件系统(如命令PARTLABEL=HFSPLUS所示),但我相当怀疑您是否有远见将 Apple HFS+ 文件系统支持包含到您的内核映像中。ifdisk /dev/loopX

GRUB 的ls命令显示,除了 CD/映像之外,您的系统还有一个 HDD,因此,这取决于您包含在系统中的存储驱动程序bzImage以及系统探测它们的顺序,或者root=/dev/sda可能root=/dev/sdb会工作。

对于一次性的、破解在一起的可启动媒体来说,这可能足够了,但如果您需要它在多个系统上工作,则需要更强大的解决方案。在这种情况下,我建议不要尝试将grub-mkrescue其用于非设计目的,而是首先设置单独的映像 USB 记忆棒/硬盘启动和 CD-ROM/DVD 启动(如果您需要它们)。一旦您更加熟悉从硬盘启动与从 CD/DVD 介质启动之间的差异,尝试将它们混合成一个同时执行这两种操作的映像将会更容易。

相关内容