我不想让 grub “搜索”任何东西。我知道我的根文件系统在哪里,并且它总是在那里(/dev/sda1),并且我不希望 grub 去查看所有连接的驱动器来查找其他根(它似乎总是找到错误的一)。
我已经能够在内核加载行中禁用 UUID 使用:
GRUB_DISABLE_LINUX_UUID=true
中/etc/default/grub
,但由此产生的/boot/grub/grub.cfg
仍然有这样的行:
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 3f8c2b36-5d8f-40ac-9b63-7d1445805925
我不想要这些。我不想让它搜索根本不。我进一步关闭了“os-probing”:
GRUB_DISABLE_OS_PROBER=true
这使它无法在其他连接的磁盘上找到我的系统的备份副本,但我不希望search
在 grub 中执行该命令的任何实例,更不用说我已经告诉它不要使用的 UUID 了。
我讨厌蛴螬。我只是希望我的机器能够以 启动root=/dev/sda1
,而不需要探测整个系统,不需要寻找可能不存在的 UUID,没有任何东西。就像 1999 年使用 LILO 启动一样。
我实际上会使用LILO 或 syslinux 之类的,如果不是 Ubuntu 使用 grub,因此如果我想跟上他们的内核更新,我几乎被迫使用它。我只是希望它是人类可能的最简单的配置(我知道这仍然会导致 200 行 grub.cfg,但是哦好吧)。
答案1
这就是grub-mkconfig
工作原理:它会自动为其发现的每个内核创建 GRUB 菜单项。但是,如果您知道自己想要什么以及在做什么,则不需要使用配置简单根本不用,因为你可以grub.cfg
直接写你的。
grub-mkconfig
确实有一些限制。虽然可以通过编辑/etc/grub.d/40_custom
或创建将额外的自定义菜单项添加到列表末尾/boot/grub/custom.cfg
,但更改菜单项的顺序或更改其标题可能需要对存储在/etc/grub.d/
.这一点将来可能会得到改善。与此同时,那些觉得这样写会更容易的人grub.cfg
鼓励那些认为直接写会更容易的人这样做(请参阅 开机, 和类似 shell 的脚本),并禁用其发行版提供的任何系统自动运行 grub-mkconfig。
在那里,您只能有一个菜单项(禁用菜单),并具有您希望的简单设置。您可以知道您想从这里启动该内核,仅此而已。
单行menuentry { }
可以是 5 行,而不是 200 行。
记住:
- 首先通过将自定义菜单条目添加到自定义条目来测试您的自定义菜单条目。
- 如果您从系统中禁用,则每当您想要更新内核时都
grub-mkconfig
需要手动更新。grub.cfg
答案2
根文件系统的信息/dev/sda1
实际上对 GRUB 完全没有用处,除了作为内核引导参数字符串的一部分root=/dev/sda1
按原样传递给 Linux 内核之外。
GRUB 需要知道的是,在加载自己的配置文件时,系统固件调用中的磁盘需要使用哪个标识符、未嵌入 GRUB 核心映像中的任何 GRUB 模块、内核和 initramfs 文件。
在经典的基于 BIOS 的系统中,该标识符的基本形式是十六进制字节:0x80 指 BIOS 检测到的第一个磁盘,0x81 指第二个磁盘,依此类推。GRUB 将这些映射到它自己的标识符:(hd0)
is 0x80、(hd1)
is 0x81 和很快。
在 UEFI 系统中,您可以运行 UEFI shell 并使用其map
命令来查看 UEFI 分区标识符(按照固件检测到它们的顺序):具有 UEFI 可识别文件系统的第一个分区是fs0:
,第二个分区是fs1:
,依此类推。整个磁盘和原始分区访问是通过诸如blk0:
. UEFI 版本的 GRUB 必须使用这些(或其机器可读 UEFI API 等效项)来识别要从中加载内容的磁盘或分区。 GRUB 主要使用自己的文件系统驱动程序,因此它将blkN:
固件的标识符映射到(hdN)
.
命令search
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1
意味着根据该grub-mkconfig
命令可用的最佳信息(这可能只是最好的猜测,特别是对于基于 BIOS 的系统),包含后续命令所需文件的分区很可能(hd0,msdos1)
在引导时,假设硬件配置获胜写完配置文件后就不要再改变了。
--set=root
告诉您此搜索命令的目的是将 GRUB 的root
变量设置为指向此搜索结果的任何分区。
因此,如果您知道此search
命令之后的任何内容所需的文件位于磁盘的第一个分区上,并且固件始终将其检测为第一个磁盘,那么您可以将此search
命令替换为:
set root=(hd0,msdos1)
注意:设置 GRUB 的root
变量与 Linux 内核的根文件系统完全无关。它的唯一目的是为使用路径名引用磁盘上文件的任何后续 GRUB 命令定义根路径(包括磁盘/分区)。
使用经典的 BIOS 式引导过程,您唯一可以合理确定的是,在 BIOS 设置中已选择任何磁盘作为可引导磁盘(如果 BIOS 设置中列出了多个磁盘,则 BIOS 当前正在尝试从中引导) boot order)将可作为 BIOS 磁盘 0x80...进行访问,因此对于 GRUB,它将是(hd0)
.
顺便说一句,Debian 和 Ubuntu “使用 GRUB”只是因为它是默认引导加载程序。如果您愿意,您可以删除 GRUB 并将其替换为您最喜欢的引导加载程序。唯一的要求是您编写自己的脚本来更新其配置在适当的目录中/etc/kernel/
:对于 GRUB,这些脚本/etc/kernel/postinst.d/zz-update-grub
是/etc/kernel/postrm.d/zz-update-grub
。这些是包管理系统和 GRUB 配置之间的唯一连接。
每当安装或删除新的内核包时,相应目录中的所有脚本都将被执行:如果您放置一个lilo
在postinst.d
和preinst.d
目录中运行的脚本,您可以像使用 GRUB 一样无缝地使用 LILO 与 Ubuntu 的更新默认。
2012 年,我有一个采用早期 UEFI 实现的系统,该系统存在固件错误,导致当时的 GRUB 出现问题;我发现 rEFInd 可以避免这个 bug,所以我用它来用 rEFInd 替换 Debian 的 GRUB。尽管固件已经更新到固定版本,并且 GRUB 已经获得了许多针对 UEFI 错误的解决方法,但我仍然保留了当时编写的简单脚本作为备份引导加载程序;这些脚本已经运行了8年。
现代版本的 Debian 实际上打包了 rEFInd 并在包中包含类似的脚本。发行版中包含的其他引导加载程序包也可能如此:如果 Ubuntu 中有 LILO 或 Syslinux 的包,您可以尝试安装它并查看该包是否包含其内核 postinstall/postrm 脚本。如果确实如此,您可能会发现它“正常工作”。
如果您有克隆磁盘或文件系统的习惯,那么如果新克隆要与原始克隆一起呈现在计算机上,您可能需要考虑更改它们的 UUID。这个问题对此有很多建议。
在具有 LVM 的 SAN 级快照的企业环境中,您必须创建克隆后立即重新统一它们,否则如果克隆和原始版本出现在同一个系统中,您将陷入痛苦的世界(曾经在那里,修复了混乱,vgimportclone
是您的朋友)。在任何其他类型的环境中,这可能仍然是一个好主意。