如何使用旧版本的内核启动?

最新的内核导致我的声音出现问题,而旧版本的内核则可以正常工作。由于我只安装了Ubuntu,所以在启动时没有显示Grub菜单。我该如何在启动时手动选择我的内核版本?
10个回答

显示Grub的最简单方法是在启动时按住SHIFT按钮。
另外,您还可以始终显示Grub而不启动任何特定的内核:
gksudo gedit /etc/default/grub

GRUB_TIMEOUT 更改为 -1 并注释掉 GRUB_HIDDEN_TIMEOUT

最后运行完成。

sudo update-grub

9警告:在设置了GRUB_HIDDEN_TIMEOUT时将GRUB_TIMEOUT设置为非零值不再支持。我已经注释掉了GRUB_HIDDEN_TIMEOUT并将GRUB_TIMEOUT设置为0。 - acidghost
只是为了明确一点:GRUB_HIDDEN_TIMEOUT是一个需要在运行“update-grub”时设置的环境变量吗? - Jonathan Hartley
1@JonathanHartley GRUB_HIDDEN_TIMEOUT/etc/default/grub 中定义。 - wjandrea
GRUB_HIDDEN_TIMEOUT 的值应该是多少呢? - alphabetasoup
3SHIFT在UEFI中无效。请尝试使用ESC键。 - foki
1嗯,看起来 GRUB_HIDDEN_TIMEOUT2.04-1ubuntu47 上似乎不再存在。设置 GRUB_TIMEOUT=-1 没问题。 - Roi
2在Grub 2.04中,该设置被称为GRUB_TIMEOUT_STYLE=hidden。将其注释掉就足够了。 - Raoul Steffen

按住Shift键启动时,将显示Grub菜单。 现在您可以选择一个较旧的内核版本。
要将较旧的内核选择为默认内核,请参阅this帖子。

2在我的情况下(Ubuntu 16.04),是左 Shift。右 Shift 不起作用。 - Bob
2如果在 grub 菜单中没有显示旧的内核(它们已经被删除),那意味着这些内核无法访问吗? - Kalamalka Kid
2我不得不使用逃脱键(而不是Shift键) - Jonathan King
1Shift键无法使用 - Coder Guy

如果您的系统中有几个内核,您可以手动设置启动哪个内核版本:
1. 在BIOS启动后按下Shift键重新启动计算机,以显示GRUB界面。 您将看到类似以下内容: GRUB启动页面 2. 选择“Ubuntu的高级选项”,并记住此菜单行的索引(从0开始计数)。在图片中索引为1。

Select concrete Kernel

3. 选择具体的内核进行引导,并记住此菜单行的索引(索引从0开始计数)。在图片上,所选内核的索引是2。
4. 启动系统。这个操作是为了在具体的内核上进行一次引导。如果你想每次都从具体的内核启动,你应该执行以下步骤:
4.1. 打开并编辑GRUB设置文件:
sudo nano /etc/default/grub

4.2. 找到行 GRUB_DEFAULT=...(默认为 GRUB_DEFAULT=0),并在引号中设置具体内核的菜单路径(请记住步骤 2 和 3 中的菜单索引)。在我的系统中,第一个索引是 1,第二个索引是 2。我将其设置为 GRUB_DEFAULT

GRUB_DEFAULT="1>2"

保存文件。
4.3. 更新GRUB信息以应用更改:
sudo update-grub

4.4. 重启后,您将自动选择菜单路径引导到内核。在我的机器上,例如是 1 -> 2。
4.5. 重新启动后,请检查内核版本: uname -r

我最开始使用了GRUB_DEFAULT="Advanced options for Ubuntu > Ubuntu, with Linux x.x.x-xx-generic",但是没有起作用... 你提供的版本 GRUB_DEFAULT="1>2" 确实有效! :) - TheQuestioner
如何在GRUB菜单中获取更多项目?如果我想要最后四个内核怎么办?系统目前在最后两个内核上出现故障。 - undefined
据我所知,所有已安装的内核都应该显示出来。你确定另外两个已经安装了或者没有被移除吗? - undefined

使用以下命令获取当前安装的内核菜单项。
ubuntu:~$ sudo grub-mkconfig | grep -iE "menuentry 'Ubuntu, with Linux" | awk '{print i++ " : "$1, $2, $3, $4, $5, $6, $7}'

0 : menuentry 'Ubuntu, with Linux 5.4.0-80-generic' --class ubuntu
1 : menuentry 'Ubuntu, with Linux 5.4.0-80-generic (recovery mode)'
2 : menuentry 'Ubuntu, with Linux 4.15.0-159-generic' --class ubuntu
3 : menuentry 'Ubuntu, with Linux 4.15.0-159-generic (recovery mode)'
4 : menuentry 'Ubuntu, with Linux 4.15.0-45-generic' --class ubuntu
5 : menuentry 'Ubuntu, with Linux 4.15.0-45-generic (recovery mode)'

根据您的需要,修改GRUB_DEFAULT=0的值。
目前我的服务器使用5.4.0-80-generic启动。
ubuntu:~# uname -srn
Linux ubuntu 5.4.0-80-generic

所以我想使用4.15.0-45-generic来启动我的系统,这是菜单项4

修改了/etc/default/grub中的GRUB_DEFAULT="1>4"值,并执行以下命令以重新生成带有修改后的GRUB_DEFAULT设置的grub配置文件。

在此解释了"1>4"格式这里

sudo update-grub

重新启动Ubuntu系统。

sudo systemctl reboot

重新启动后,我的Ubuntu服务器仍然使用旧内核4.15.0-45-generic启动

ubuntu:~# uname -srn
Linux ubuntu 4.15.0-45-generic

4这是正确的答案。非常感谢你。 - Tom
你是说你要通过编辑GRUB-DEFAULT的值,将/etc/default/grub中的值从0改为1>4 - Amanda

在启动时,当 GRUB 出现并列出条目时,请选择第二个条目,即 Ubuntu 的高级选项,您可以看到以前安装的不同旧内核版本,您可以选择其中一个适合您的版本。 否则,您可以进入 grub.cfg 并将所需的内核版本粘贴到当前安装的内核条目顶部。两种方法都可以使用。

请使用以下命令安装先前的内核:
sudo apt-get install linux-image-3.0.0-12-generic linux-headers-3.0.0-12-generic

然后重新启动。您将被提示选择内核。

16.04及更高版本

  1. 在计算机启动时出现主板/计算机制造商的标志性画面,与BIOS,快速按住Shift键,这将带出GNU GRUB菜单。(如果您看到Ubuntu标志,则已错过了进入GRUB菜单的时机。)对于UEFI,请按下(可能要按几次)Esc键以进入GRUB菜单。有时制造商的标志画面是Windows引导加载程序的一部分,因此当您启动计算机时,它会直接进入GRUB画面,然后按Shift键是不必要的。

  2. 从GRUB屏幕中选择Ubuntu的高级选项并按Enter

enter image description here

一个新的紫色屏幕将出现,显示一个内核列表。使用↑和↓键选择要突出显示的条目。按Enter键启动所选的内核,按'e'键在启动之前编辑命令,或按'c'键进入命令行。按Esc键返回上一个菜单。

enter image description here

防止Ubuntu卸载旧的内核版本

如果您已确定可以通过使用旧的内核版本成功启动Ubuntu,下一步是按照this answer中的说明,防止Ubuntu自动卸载该内核版本。如果您不希望autoremove删除特定的内核版本包,可以使用以下命令手动标记其为已安装:sudo apt-mark manual package-name。有关要标记为手动安装的Linux内核包的更多信息,请阅读链接的答案。


1尽管与这个更短的答案相同:https://askubuntu.com/a/584738/307523,但你的回答更进一步,附有屏幕截图,并提到了使用`Shift`键来首先启动grub。 - WinEunuuchs2Unix


Jackkobec的回答描述了一种查看grub.cfg并滚动浏览源代码以找到菜单编号的方法。更简单的方法是使用这个脚本

Grub Version: 2.02~beta2-36ubuntu3.22


         ┌───────────┤ Use arrow, page, home & end keys. Tab toggle option ├────────────┐
         │ Menu No.     ----------- Menu Name -----------                               │ 
         │                                                                              │ 
         │  1>3  Ubuntu, with Linux 4.15.0-55-generic                                  ↑│ 
         │  1>6  Ubuntu, with Linux 4.15.0-54-generic                                  ▒│ 
         │  1>9  Ubuntu, with Linux 4.14.134-0414134-generic                           ▒│ 
         │  1>12 Ubuntu, with Linux 4.14.120-0414120-generic                           ▮│ 
         │  1>15 Ubuntu, with Linux 4.14.114-0414114-generic                           ▒│ 
         │  1>18 Ubuntu, with Linux 4.14.110-0414110-generic                           ▒│ 
         │  1>21 Ubuntu, with Linux 4.14.98-041498-generic                             ▒│ 
         │  1>24 Ubuntu, with Linux 4.14.89-041489-generic                             ▒│ 
         │  1>27 Ubuntu, with Linux 4.14.78-041478-generic                             ▒│ 
         │  1>30 Ubuntu, with Linux 4.14.70-041470-generic                             ▒│ 
         │  1>33 Ubuntu, with Linux 4.4.0-157-generic                                  ▒│ 
         │  1>36 Ubuntu, with Linux 3.16.60-031660-generic                             ▒│ 
         │  1>36 Ubuntu, with Linux 3.16.60-031660-generic                             ▒│ 
         │  2    Ubuntu 18.04.1 LTS (18.04) (on /dev/nvme0n1p10)                       ▒│ 
         │  3    Advanced options for Ubuntu 18.04.1 LTS (18.04) (on /dev/nvme0n1p10)  ▒│ 
         │  3>0  Ubuntu (on /dev/nvme0n1p10)                                           ↓│ 
         │                                                                              │ 
         │                                                                              │ 
         │                     [Display Grub Boot]            Exit                      │ 
         │                                                                              │ 
         └──────────────────────────────────────────────────────────────────────────────┘ 




注意:在这个例子中,使用了grub-menu.sh short来调用脚本。参数short会抑制这些行的显示:
     │  1>10 Ubuntu, with Linux 4.14.134-0414134-generic (upstart)                 ▒│ 
     │  1>11 Ubuntu, with Linux 4.14.134-0414134-generic (recovery mode)           ▒│ 

控制键

在浏览条目后(您可以使用鼠标滚轮或箭头键),按下Escape返回到命令行。

如果按下Enter,将显示与该条目相关的grub命令:

menuentry 'Ubuntu, with Linux 4.14.134-0414134-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.14.134-0414134-generic-advanced-b40b3925-70ef-447f-923e-1b05467c00e7' {
recordfail
savedefault
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root b40b3925-70ef-447f-923e-1b05467c00e7
else
search --no-floppy --fs-uuid --set=root b40b3925-70ef-447f-923e-1b05467c00e7
fi
echo 'Loading Linux 4.14.134-0414134-generic ...'
linux /boot/vmlinuz-4.14.134-0414134-generic root=UUID=b40b3925-70ef-447f-923e-1b05467c00e7 ro noplymouth fastboot acpiphp.disable=1 pcie_aspm=force vt.handoff=7 i915.fastboot=1 nopti nospectre_v2 nospec mem_sleep_default=deep
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-4.14.134-0414134-generic
}
Press <Enter> to continue

更新grub以引导先前的内核

每个菜单项都有一组grub命令。编译后的条目都存储在/boot/grub/grub.cfg文件中。

在这个例子中,我们想要将菜单编号`1>9>设置为默认值,所以我们使用:

sudo -H gedit /etc/default/grub

然后找到这一行:

GRUB_DEFAULT=0

将其更改为这样:
GRUB_DEFAULT="1>9"

然后保存文件并运行
sudo update-grub

重启到特定的内核,其版本号和类型可以从ls /boot | grep vmlinuz命令执行中获取。
创建脚本,内容如下:$ vim.tiny kernboot.sh
    kernel="5.3.0-40-generic"
    kernlist="$(grep -i "menuentry '" /boot/grub/grub.cfg|sed -r "s|--class .*$||g")"
    printf "%s$kernlist\n" | logger
    menuline="$(printf "%s$kernlist\n"|grep -ne $kernel | grep -v recovery | cut -f1 -d":")"
    menunum="$(($menuline-2))"
    grub-reboot "1>$menunum"
    echo "The next grub's menu entry will be choosen after the reboot:\n 1>$menunum" | logger

    reboot

给脚本添加执行权限并运行它。
$ chmod +x kernboot.sh
$ sudo ./kernboot.sh

脚本可以通过sudo crontab -e命令放置到cron中,并使用@reboot /path/to/script命令执行。
我在19.10和20.04上尝试过,结果符合预期。这个脚本,但是不包含reboot命令,也可以通过sudo crontab -e将其放置到root的cron中:@reboot /pathto/kernboot.sh,结果是,在下次启动时,操作系统将使用脚本中指定的内核启动。

在Ubuntu 20.04上对我也起作用了。 - Ryan w