我不明白它是如何知道要加载哪个内核映像的?我有这么多。一旦我创建了自己的内核并重新编译。它如何知道这是要加载的?
答案1
简而言之,是的,如果您更改 /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
代码看起来相当复杂且不易定制。