grub 引导加载程序如何知道?

grub 引导加载程序如何知道?

我不明白它是如何知道要加载哪个内核映像的?我有这么多。一旦我创建了自己的内核并重新编译。它如何知道这是要加载的?

答案1

以下是我从信息 grub和这个grub 教程

简而言之,是的,如果您更改 /boot/grub/grub.cfg 文件,grub2 引导加载程序将读取这些更改并采取相应措施。

  • 警告就是如果你犯了一个小错误,你的系统将无法启动(虽然 grub2 本身可以运行,并且你可以使用 grub shell 启动,只要三个命令,如果你知道你在做什么)。因此,你不必在 grub.cfg 中实际编辑启动项,复制它,并为新的菜单项赋予新名称。如果新菜单项正确启动,您可以将其设为新的默认值(见下文)或删除旧的菜单项。

  • 并发症默认情况下,每当 Ubuntu 推送 grub 或内核更新时,它都会完全重写grub.cfg(通过 shell 脚本 /usr/sbin/update-grub2)。因此,如果您手动更改 grub.cfg 来启动自定义内核,这些更改可能会被覆盖。

解决这个问题的方法是,根本不要弄乱 grub.cfg,而是将自定义内核菜单项添加到 /etc/grub.d/40_custom 的末尾,然后运行#sudo update-grub2

(这将确保即使 Ubuntu 推送了 grub 或内核更新,您的自定义内核也将始终位于 grub 的 grub.cfg 文件中)。

你仍需要确保你的内核默认启动。通过编辑文件 /etc/default/grub 来实现

改变线路

GRUB-DEFAULT=0

GRUB-DEFAULT='My super duper kernel 3.11.xxx'

引用的字符串是确切地grub.cfg 中对应菜单项的引号是什么

您可能需要再次运行 update-grub2。

就这样,你已经完成了。

例子:

我有以下内核和initrd:

vmlinuz-3.11.0-18-generic

initrd.img-3.11.0-18-generic

并希望默认启动以下自定义内核

my_super_duper_kernel_3.11

initrd.img-my_super_duper_kernel_3.11

1) 我在 /boot/grub/grub/cfg 中查找当前条目。(请注意,每个菜单条目中似乎都有很多不必要的内容 - 请参阅本文末尾的简要内容)。

menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os
$menuentry_id_option 'gnulinux-simple-83af7d46-f6f8-4161-b7a4-47c44de0dd5e' {


... stuff deleted for brevity...

#this specifies first hard disk, first partition (i have a separate /boot partition)    
set root='hd0,msdos1'

linux   /vmlinuz-3.11.0-18-generic root=/dev/mapper/linuxlvm-lvubuntu ro   quiet splash $vt_handoff

initrd  /initrd.img-3.11.0-18-generic

}

2) 我将菜单项附加到 /etc/grub.d/40_custom,并用新的菜单项名称、内核映像和 initrd 替换:

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

#menu entry changed. It can be anything as long as it's unique
menuentry 'my_super_duper_kernel_3.11' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-83af7d46-f6f8-4161-b7a4-47c44de0dd5e' {


set root='hd0,msdos1'

#kernel image here must match the one in /boot
linux   /my_super_duper_kernel_3.11 root=/dev/mapper/linuxlvm-lvubuntu ro   quiet 

splash $vt_handoff

#initrd image, if you use one
initrd  /initrd-my_super_duper_kernel_3.11

#don't forget the closing bracket
}

3)运行#sudo update-grub2

4)重新启动。您应该在引导加载程序列表的底部看到新的内核。

5) 通过编辑 /etc/default/grub 中的 default 行将其设为默认值。它必须与你在 /etc/grub.d/40_custom 中紧接着在引号中输入的内容完全匹配menuentry=

GRUB-DEFAULT='My super duper kernel 3.11'

6)不确定是否有必要,但重新运行“#sudo update-grub2

背景信息:

术语:“引导加载程序称为 grub2,但人们通常仍将其称为‘grub’。因此,如果您在 Google 上搜索有关该主题的帮助,请确保专门搜索 grub2。仅搜索‘grub’就会显示有关旧 grub 加载程序的一些过时信息(仍在使用,但已重命名为‘grub-legacy’)。

它如何知道:Grub2 由一小段安装好的软件 (boot.img) 组成(通常在磁盘的 MBR 上),其中硬编码了 grub.cfg 文件在磁​​盘上的位置,以及实际启动 Linux 内核的更多软件(core.img 和各种 *.mod 文件)。因此 boot.img 知道要查找 core.img,而 core.img 又会读取 grub.cfg

grub.cfg 由 shell 脚本 /usr/sbin/update-grub2 生成。它会执行 /etc/grub.d/ 中的所有可执行脚本(按字母顺序执行,因此 10_linux 会在 40_custom 之前执行,等等),并将其输出发送到 grub.cfg

基本文件 除非您使用非标准文件系统或硬件,否则您只需几行代码即可在带有 grub 的标准 PC 上启动 Linux 内核。其他内容用于图形启动画面,我不知道还有什么(以下内容使用 ext4 /boot 分区和 lvm-ext4 中的 / 进行了测试):

menuentry 'foo' {
set root='hd0,msdos1' #depends on your partitioning scheme 

linux   /kernel_image root=/dev/mapper/linuxlvm-lvubuntu ro  
#root= should be set to whatever /etc/fstab (or the mount command) says for the device that / is mounted on.

#initrd image, if you use one
initrd  /initrd-my_super_duper_kernel_3.11
}

答案2

它不知道。它只会在目录中查找某些文件(initrd*vmlinuz*/boot并写入配置文件(/boot/grub/grub.cfg)。您可以使用以下方法更新该文件

sudo update-grub2

或者

sudo grub2-mkconfig -o /boot/grub/grub.cfg

然后,在启动阶段,GRUB 会查看该文件并使用其中存储的信息。很简单。

示例输出:

$ sudo 更新-grub2
正在生成 grub.cfg ...
找到 Linux 映像:/boot/vmlinuz-3.11.0-18-generic
找到 initrd 映像:/boot/initrd.img-3.11.0-18-generic
找到 memtest86+ 映像:/memtest86+.bin
  未找到卷组
完毕

答案3

回答你的最后一个问题:

你可以把新的菜单项任何地方在 /etc/grub.d/40_custom 中。

然后编辑 /etc/default/grub,并将 DEFAULT 更改为姓名添加到 40_custom 的菜单项。(最好使用名称而不是 0 索引数字,因为它允许以后添加或删除更多内核映像:请参阅grub2 信息页面)。

然后确保运行sudo update-grub2 (否则您的更改将不会写入 grub.cfg)。

理由:40_custom 被添加到 grub 菜单中,位于 grub-update2 找到的任何内核映像下方,因此顺序之内40_custom 不会覆盖 10_linux 找到的内核。

答案4

详细说明 Danatela 的回答,存在 grub-mkconfig 帮助脚本,其中/etc/grub.d/定义 GRUB 应该在哪里寻找内核(10_linux)以及是否应该包含已安装的其他操作系统(可以通过添加到来 30_os-prober关闭)。GRUB_DISABLE_OS_PROBER=true/etc/default/grub

您可以查看代码10_linux以了解 GRUB 如何“找到”内核并尝试包含它们,或者将您自己的代码添加到其中40_custom,但这可能有点困难,因为10_linux代码看起来相当复杂且不易定制。

相关内容