update-grub 如何决定将哪个内核设置为默认内核?

update-grub 如何决定将哪个内核设置为默认内核?

我正在运行 ubuntu 20.04,安装了许多内核,从默认内核到我在本地编译的自定义内核。当我运行时sudo update-grub,我当前正在摆弄的内核(即上次编译的内核)总是被神奇地选为启动的默认选项。

这是如何工作的?update-grub 如何知道应该将哪个内核设置为默认内核?我发现文档关于这个话题的评论令人恼火地贫乏:

它的工作原理是在 /boot 中查找所有以“vmlinuz-”开头的文件。这些文件将被视为内核,并为每个文件创建 grub 菜单条目。

这很好,但是如何

答案1

update-grub调用grub-mkconfig,后者又运行 中的 shell 脚本/etc/grub.d。其中之一是/etc/grub.d/10_linux,它使用 shell 函数version_find_latest不断迭代剩余 Linux 内核列表,从最新到最旧。

shell 函数version_find_latest在 中定义/usr/share/grub/grub-mkconfig_lib,使用辅助函数version_test_gt(也在同一文件中定义)。此函数使用 sed 正则表达式的混合来检测预发布版本、git 版本等,最后求助于 来dpkg --compare-versions比较两个点修订字符串。

您实际上可以在 shell 中尝试它,而无需编译任何内核或更改任何 grub 配置:

$ source /usr/share/grub/grub-mkconfig_lib
$ version_find_latest vmlinuz-5.6.7-aaa vmlinuz-5.1.12 vmlinuz-5.6.7-git
vmlinuz-5.6.7-aaa

答案2

这不是一个权威的答案,如果有更好的答案,它将被删除。

grub 菜单上的内核顺序主要按版本排序。但是 grub 似乎知道发布候选版本和最终版本之间的区别。除了“.”之外,它似乎还将“-”字符视为分隔符。

示例(经过编辑,之后grep menuentry /boot/grub.cfg):

    menuentry 'Ubuntu, with Linux 5.8.0-050800-lowlatency' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-050800-lowlaten>
    menuentry 'Ubuntu, with Linux 5.8.0-050800-lowlatency (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp-ps2' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-qp-sp-ps2-advan>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp-ps2 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp-powersave' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-qp-sp-pow>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp-powersave (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-qp-sp-advanced-0ac3>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-qp-sp (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-qp->
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-stock' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-stock-advanced-0ac3>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-stock (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-sto>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-spv2' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-spv2-advanced-0ac356>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-spv2 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-spv2>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds4' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds4-advanced-0ac356c1>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds4 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds4-r>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds3' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds3-advanced-0ac356c1>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds3 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds3-r>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds1' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds1-advanced-0ac356c1>
    menuentry 'Ubuntu, with Linux 5.8.0-rc1-ds1 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.8.0-rc1-ds1-r>
    menuentry 'Ubuntu, with Linux 5.7.0-doug-hwp' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.7.0-doug-hwp-advanced-0ac356>
    menuentry 'Ubuntu, with Linux 5.7.0-doug-hwp (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.7.0-doug-hwp>
    menuentry 'Ubuntu, with Linux 5.7.0-050700rc6-lowlatency' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.7.0-050700rc6-lo>
    menuentry 'Ubuntu, with Linux 5.7.0-050700rc6-lowlatency (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.>
    menuentry 'Ubuntu, with Linux 5.7.0-050700rc3-lowlatency' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.7.0-050700rc3-lo>
    menuentry 'Ubuntu, with Linux 5.7.0-050700rc3-lowlatency (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.>
    ...

上面的列表中5.8.0-rc1-ds4实际上是最近编译的,但在列表中排在第 7 位。列表中的第一个实际上是来自主线 PPA 的 rc1,文件名不正确,因为它实际上是 -rc1。这个5.8.0-rc1-qp-sp-ps2实际上相当旧,我认为是额外的“-”分隔符导致了它在列表中的位置。

相关内容