Ubuntu修改GRUB默认启动内核全攻略:原理、配置与避坑指南

发布时间:2026/9/16 18:25:34
Ubuntu修改GRUB默认启动内核全攻略:原理、配置与避坑指南 系统里装了好几个内核版本结果每次开机都要在GRUB菜单里盯着倒数计时手忙脚乱地选内核这种经历我太熟悉了。被逼到这个份上多半是因为新内核和NVIDIA驱动打架、某个硬件模块只在旧内核下工作正常或者跑实时内核PREEMPT_RT需要锁定版本。不管你是哪种情况解决思路都落在同一个地方GRUB配置。这篇文章我会把Ubuntu下修改GRUB默认启动内核的几种方案、底层原理和实操中踩过的坑一次性讲透从查看菜单到调整配置再到验证照着做就行。1. 为什么需要修改默认启动内核1.1 常见的多内核共存场景先说说我在实际中遇到最多的情况。Ubuntu每次系统更新都会自动升级内核版本默认会在GRUB菜单里保留旧内核方便出问题时回退。但这样一来GRUB菜单里往往有好几行Ubuntu和Advanced options for Ubuntu默认启动的是最新内核。什么情况下你需要手动修改默认内核根据我的经验下面几类场景最常见新内核和显卡驱动不兼容。装了NVIDIA专有驱动后某次内核升级驱动模块编译失败开机进桌面直接黑屏或分辨率异常把默认内核指回旧版本是最快的止损方式。工控机、服务器需要固定内核版本。跑采集卡、运动控制卡、EtherCAT主站这类依赖内核模块的应用必须用经过验证的内核版本不能放任内核自动升级。这也是实时内核场景下最标准的操作。新内核存在回归问题。某些内核版本在特定硬件平台上的休眠唤醒、网络驱动、USB控制器方面会有反复这时手动锁定旧内核是比较理性的选择。测试内核。你想试用候选版本但希望系统默认还是走稳定内核出问题随时回退。提示在修改默认内核之前我强烈建议先通过GRUB菜单手动启动一次目标内核确认它在你的机器上工作正常再把它设为默认。跳过这一步很容易把自己锁在门外。1.2 GRUB在启动流程中的角色GRUBGRand Unified Bootloader是Linux系统中最常用的引导加载程序。它的职责简单说就是按下电源键之后BIOS/UEFI从磁盘上把GRUB代码加载进来GRUB读取/boot/grub/grub.cfg配置文件然后把内核镜像vmlinuz和initrd加载到内存接着把控制权交给内核。整个引导过程中GRUB菜单项决定了加载哪个内核、以什么参数加载。这里有一个很多新手会混淆的点/etc/default/grub是用户编辑的模板配置而/boot/grub/grub.cfg是GRUB启动时真正读取的运行时配置。我们每次运行update-grub或grub-mkconfig系统会把/etc/default/grub里的设置、/etc/grub.d/目录下的脚本以及当前系统中已安装的内核信息合并起来重新生成一份grub.cfg。所以修改默认内核的完整链路是改/etc/default/grub → 执行update-grub → 重启。这条链路是整个操作的主线后边所有方案都围绕它展开。2. 动手前的准备看清系统现状2.1 确认当前内核与候选内核操作之前先搞清楚系统里都有哪些内核。我的习惯是先看当前正在用的uname -r输出类似5.15.0-91-generic这就是当前内核版本。然后看系统里安装了哪些内核镜像包dpkg --list | grep linux-image如果你看到linux-image-5.15.0-91-generic、linux-image-5.15.0-92-generic这些条目就说明系统里装了多个内核。另外还要注意linux-headers包那是编译内核模块时用的头文件一般不影响启动顺序但删除内核时建议一起清理。也可以查看/boot目录ls -lh /boot/vmlinuz-*这个命令会把所有内核镜像文件列出来附带文件大小和修改时间看起来更直观。我个人更习惯用dpkg来查因为dpkg能同时告诉你内核包的状态ii表示已安装和架构这个细节对于需要确认软件包来源、准备做双系统清理的人来说非常实用。2.2 查看GRUB菜单的真实顺序修改默认内核最关键的一步是搞清楚GRUB菜单里每一项的真实排列。GRUB菜单项的序号从0开始第一个菜单项是0第二个是1以此类推。查看菜单项最可靠的方式是直接读grub.cfggrep -E ^menuentry|^submenu /boot/grub/grub.cfg这条命令会把所有顶层菜单项和子菜单项列出来。Ubuntu的GRUB菜单结构通常长这样Ubuntu顶层菜单项Advanced options for Ubuntu顶层子菜单Ubuntu, with Linux 5.15.0-92-genericUbuntu, with Linux 5.15.0-92-generic (recovery mode)Ubuntu, with Linux 5.15.0-91-genericUbuntu, with Linux 5.15.0-91-generic (recovery mode)...注意Ubuntu默认的第一项Ubuntu实际上是指向Advanced options for Ubuntu子菜单里最新内核那条的而不是一个简单的独立菜单项。这一个细节在后边用序号方式设置默认值的时候特别容易踩坑。还有个更便于脚本处理的命令awk -F\ /menuentry |submenu / {print $1$2} /boot/grub/grub.cfg这条命令用单引号作为分隔符把每个菜单项类型和完整名称提取出来输出结果更方便人工对照。前后两条命令建议都试一下选择自己看着顺眼的方式。2.3 理解GRUB配置体系修改默认启动项日常接触的核心是/etc/default/grub这个文件。打开看一下sudo cat /etc/default/grub典型的内容是这样GRUB_DEFAULT0 GRUB_TIMEOUT_STYLEhidden GRUB_TIMEOUT10 GRUB_DISTRIBUTORlsb_release -i -s 2 /dev/null || echo Debian GRUB_CMDLINE_LINUX_DEFAULTquiet splash GRUB_CMDLINE_LINUX这几个变量里跟本文主题关系最密切的是GRUB_DEFAULT它控制默认启动哪个菜单项。GRUB_TIMEOUT控制菜单等待时间GRUB_TIMEOUT_STYLEhidden表示不显示菜单直接按超时选择默认项。理解了GRUB_DEFAULT的几种取值方式后面才能真正按需修改数字GRUB_DEFAULT0代表第一个菜单项菜单项名称GRUB_DEFAULTAdvanced options for UbuntuUbuntu, with Linux 5.15.0-91-genericsaved配合GRUB_SAVEDEFAULTtrue用grub-set-default来指定对于大多数固定场景我建议优先用菜单项名称或saved方式数字方式只在临时改动时用。3. 修改默认内核的几种实用方案3.1 方案一GRUB_DEFAULT指定菜单项序号最直接的思路GRUB_DEFAULT0默认是第一个菜单项那我改成目标内核在菜单里的序号不就行了比如上面的例子我想默认启动5.15.0-91-generic它在子菜单里的序号是2因为第0项是5.15.0-92第1项是它的recovery mode第2项才是5.15.0-91。那么GRUB_DEFAULT12这里1表示第二行菜单Advanced options for Ubuntu子菜单的序号2表示子菜单内第三条也就是5.15.0-91-generic。中间的大于号是分隔符用来表示进入子菜单。注意这个写法有个隐藏的坑。如果你只写一个数字2GRUB会把它解释为顶层菜单的第三项而顶层一般只有Ubuntu和Advanced options for Ubuntu两项根本不指向你想启动的实际内核。所以在有子菜单的情况下父菜单序号子菜单序号是必须完整的写法序号之间的符号是英文半角的大于号不要写成别的字符。这种用序号的方式最大的问题就是可读性差而且一旦内核升级GRUB菜单项的排列顺序变化序号就乱了。所以对于要长期保持的配置我不太推荐用序号方式它更适合临时改一下、确认没问题就改回来的场景。3.2 方案二通过菜单项名称锁定内核我更推荐的方式是用菜单项的完整名称来指定默认内核。在/etc/default/grub里这样写GRUB_DEFAULTAdvanced options for UbuntuUbuntu, with Linux 5.15.0-91-generic这里的用来分隔顶级菜单和子菜单后面的字符串必须和grub.cfg里的menuentry名称完全一致。用名称锁定有一个好处即使系统里又装了一个新内核只要目标内核还在这个字符串就不会变默认项不会发生漂移。有个小技巧如果你嫌手敲名称容易拼错可以先从grub.cfg里把名称复制出来grep menuentry /boot/grub/grub.cfg | cut -d -f2把输出里那一长串带with Linux的文本直接粘到配置文件里再手动加上前面Advanced options for Ubuntu前缀即可。注意双引号内不要多出空格也不要手动加引号之外的特殊字符否则GRUB匹配不到会回退到第一个菜单项。3.3 方案三saved方式配合grub-set-default第三种方式适合我可能频繁切换不同内核版本的场景。原理很简单GRUB会把上次选择启动的菜单项记录下来以后默认启动上次选择的那一项。具体配置/etc/default/grub里设置两行GRUB_DEFAULTsaved GRUB_SAVEDEFAULTtrue然后更新配置sudo update-grub重启之后GRUB菜单会记住你开机时手动选择的内核并把它的序号写入/boot/grub/grubenv文件下一次开机默认启动的就是它。如果你想不通过菜单直接在命令行里指定默认项可以用sudo grub-set-default Advanced options for UbuntuUbuntu, with Linux 5.15.0-91-generic这个命令会把默认项写入grubenv效果等同于手动在菜单里选了那一项。saved方式的优点在于灵活特别适合调试内核的场景你可以从旧内核启动测试完再手动引导新内核系统会记住你最后一次的选择。缺点是你必须在每次重启后注意确认GRUB菜单里选对了项不然默认项可能被意外修改。3.4 方案四临时切换用grub-reboot有一种更轻的操作不需要修改任何配置文件只需要这一次开机用某个内核之后还是用原来的默认项。执行sudo grub-reboot Advanced options for UbuntuUbuntu, with Linux 5.15.0-91-generic sudo rebootgrub-reboot只会影响下一次启动不会修改持久化的默认配置。它的实现原理是把目标菜单项写入grubenv中的next_entry变量GRUB在启动时会优先读取next_entry用完即清。这个命令在我处理新内核可能有问题先试一次旧内核的场景里特别好用相当于给系统做了一个单次启动的快照切换。我个人在调试内核参数、做硬件兼容性验证时最常用的其实是这个命令。因为不需要改配置文件也不用担心改完忘了改回来非常适合只试一次的场景。四种方案的对比我整理成一张表方案配置方式适用场景缺点序号GRUB_DEFAULT12临时快速指定可读性差内核升级后易偏移名称GRUB_DEFAULTAdvanced options for Ubuntu...长期固定名称必须精确匹配savedGRUB_DEFAULTsaved grub-set-default频繁切换默认项会跟随手动选择变化grub-reboot命令行指定单次临时试用仅影响下一次启动4. 刷新配置与启动验证4.1 update-grub到底做了什么不管用哪种方案修改了/etc/default/grub最后一步都需要刷新GRUB配置。在Ubuntu上就是执行sudo update-grub这个命令是一个脚本封装底层调用的是grub-mkconfig -o /boot/grub/grub.cfg。它会扫描/etc/grub.d/目录下的脚本00_header、10_linux、30_os-prober等结合/etc/default/grub里的参数重新生成grub.cfg。简单理解就是模板配置 检测逻辑 最终配置也就是说你改完模板之后必须让系统重新翻译一遍grub.cfg才会带上你的新设置。执行update-grub后观察输出有没有出现你期望的内核名称。它通常会打印类似Found linux image: /boot/vmlinuz-5.15.0-92-generic Found initrd image: /boot/initrd.img-5.15.0-92-generic Found linux image: /boot/vmlinuz-5.15.0-91-generic Found initrd image: /boot/initrd.img-5.15.0-91-generic done如果你改了GRUB_DEFAULT但看不到任何found输出说明update-grub没有正确执行多半是权限不够、磁盘空间不足或其他问题。另外注意update-grub需要root权限别漏了sudo。有一点要提醒如果GRUB_DEFAULT指向的菜单项名称在当前系统里不存在update-grub不会报错它只是照常生成配置重启时GRUB找不到对应菜单项会静默回退到第一个可启动项。所以刷新完配置后最好再看一眼grub.cfg内容确认目标内核确实在菜单里。4.2 重启后如何验证生效完成配置后重启系统sudo reboot重启后进入系统我建议第一件事就是确认当前到底用了哪个内核uname -r如果你看到的就是目标内核版本说明配置生效了。有时候你以为改对了但uname -r出来还是老内核这时候不要慌我遇到过好多次原因基本集中在几个点没执行update-grubgrub.cfg还是旧的修改/etc/default/grub时语法写错了比如引号没闭合、前后多了空格GRUB_DEFAULT的值指向了不存在的菜单项名称UEFI机器上出现了多个GRUB引导项BIOS实际引导的是另一个EFI分区里的GRUB最后一种情况在双系统、多硬盘环境下特别常见。你改的可能是某个磁盘上的GRUB但主板实际引导的是另一个EFI分区里的GRUB。排查方法很简单开机时手动进入BIOS/UEFI设置界面确认默认引导项到底是哪个或者用efibootmgr命令查看当前引导顺序efibootmgr这个命令会显示EFI引导项的列表你可以看到当前BootOrder指向哪个设备。如果系统没有efibootmgr可以用apt install efibootmgr安装。如果你发现引导顺序里排在最前面的不是Ubuntu的grubx64.efi那修改/etc/default/grub大概率不会生效得先把引导顺序调整到正确的EFI分区。4.3 配置撤销或回滚改完配置后如果发现不对劲恢复原状也简单。编辑/etc/default/grub把GRUB_DEFAULT改回0然后sudo update-grub如果你不确定改之前是什么值Ubuntu默认就是GRUB_DEFAULT0。还有一种更稳妥的方式改配置文件之前先备份sudo cp /etc/default/grub /etc/default/grub.bak出问题时恢复备份再update-grub即可。不要小看这一步在生产机器上操作时备份一下配置文件成本几乎为零但真遇到配置写错、还要现场救急的时候这一条能帮你省下不少时间。5. 常见坑与排查经验5.1 GRUB菜单序号偏移问题用序号方式配置默认内核最让人头疼的就是内核升级后序号乱了。比如你设置了GRUB_DEFAULT12本来指向前一个内核。结果某天apt自动升级内核系统装了一个5.15.0-93菜单排列变成了UbuntuAdvanced options for Ubuntu5.15.0-935.15.0-93 (recovery mode)5.15.0-925.15.0-92 (recovery mode)5.15.0-91你要锁定那个原来序号2对应的是5.15.0-91现在变成了5.15.0-92你的默认项悄悄变成了另一个新内核而你自己可能过了很久才发现。所以我前面才反复强调如果需要长期固定用菜单项名称而不是序号。判断自己是不是踩了序号偏移的坑最简单的方法是执行update-grub后重新检查一遍grub.cfg里的菜单顺序和自己配置文件里的序号对照一下。这个习惯我基本已经养成了每次升级内核后都会顺手看一眼。5.2 内核升级后默认项被重置这个问题在20.04之后的Ubuntu上其实已经有改进了但偶尔还是会遇到。原因通常是/etc/default/grub里的GRUB_DEFAULTsaved配合GRUB_SAVEDEFAULTtrue时GRUB会默认把最后一次手动选择当作默认。如果你在某个时间点手滑在菜单里选了一次别的内核之后默认项就会跟着变。避免办法有两种一是用固定的菜单项名称别用saved二是在确认默认项正确之后重新执行一次grub-set-default把grubenv里的记录写死。我个人更推荐第一种省心。5.3 GRUB菜单不出现的处理有同学改完配置发现开机直接进系统GRUB菜单一闪而过甚至完全看不到想手动选内核都没机会。这是因为/etc/default/grub里有这么一行GRUB_TIMEOUT_STYLEhidden GRUB_TIMEOUT0GRUB_TIMEOUT_STYLEhidden会隐藏菜单GRUB_TIMEOUT0表示等待时间为0系统会直接用默认项启动。如果你需要经常切内核建议把GRUB_TIMEOUT改成3或5并且把GRUB_TIMEOUT_STYLE设为menu。注意这两个变量必须配套修改只改一个不会生效。另外有一个救命技巧即使GRUB菜单被隐藏开机时按住Shift键传统BIOS模式或反复按Esc键UEFI模式也能把菜单呼出来。当你把默认项改错、系统都快启动不起来的时候这个技巧能救急。5.4 清理旧内核的正确姿势修改默认内核之后很多人会顺手想把旧内核删掉腾出/boot空间。但删除内核一定要小心别把当前正在使用的内核删了。我的建议是先确认当前内核uname -r然后删除不需要的内核镜像sudo apt remove --purge linux-image-5.15.0-91-generic linux-headers-5.15.0-91-generic如果想更省事也可以sudo apt autoremoveautoremove会清理不再需要的旧内核包但有的时候它也会把你还想保留的内核一并清掉所以执行前先看一下它将移除的包列表确认没有当前正在运行的版本再继续。删除完成后记得sudo update-grub让GRUB菜单同步更新。这个顺序很重要如果你先删内核再update-grub没问题但如果先update-grub再删内核grub.cfg里就会残留指向已删除内核的菜单项启动时GRUB会报错。5.5 遇到grub rescue模式怎么办聊到GRUB相关的坑就不得不提让无数人头疼的grub rescue模式。屏幕上一行grub minimal bash like line editing is supported说明GRUB找不到正常的配置文件或内核镜像进入了最小化救援环境。这个情况我见过太多次了常见原因有两个一是删内核删出了事比如不小心把包含当前内核的vmlinuz文件从/boot里删掉了或者操作时断电导致grub.cfg损坏。二是双系统安装或Ubuntu重装时GRUB安装位置不对导致引导记录指向了不存在的分区。如果是第一种情况你大概率需要从Ubuntu安装U盘启动进入Live环境后chroot到系统里重新安装GRUB。下面是核心步骤前提是你能在Live环境中挂载系统分区sudo mount /dev/sda2 /mnt sudo mount /dev/sda1 /mnt/boot/efi sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys sudo chroot /mnt grub-install /dev/sda update-grub exit sudo reboot这里的/dev/sda2要替换成你的根分区/dev/sda1是EFI分区UEFI模式下必须有/dev/sda是目标磁盘。如果你的/boot是独立分区还需要在chroot前额外挂载sudo mount /dev/sdXX /mnt/boot。这个操作能重建GRUB引导一般都能救回来。如果是第二种情况麻烦在于哪个磁盘才是真正的启动盘。我的排查思路是先查看当前系统的分区布局确认系统安装在哪个硬盘上然后用grub-install把GRUB装到对应磁盘的EFI分区里最后检查主板启动顺序。注意grub-install是风险较高的操作在双系统和多硬盘环境里尤其要小心。如果你不确定某个分区是根分区还是EFI分区先执行lsblk -f看清楚不要在没确认的情况下乱挂载、乱安装。5.6 多系统环境下GRUB的默认项既然要聊双系统安装Ubuntu我也顺带提一句。双系统环境下GRUB菜单往往会多出Windows Boot Manager这一项由30_os-prober脚本检测。如果你想修改默认启动的系统依然可以用GRUB_DEFAULT来指定比如GRUB_DEFAULTWindows Boot Manager但Windows Boot Manager在不同主板上的显示名称可能有差异有的显示成Windows Boot Manager (on /dev/sda2)这里的名称同样要和grub.cfg里的menuentry完全一致。多系统环境下建议先用grep命令把真实菜单名称抓出来再填到配置里。另外双系统环境下如果网络、硬件和某个内核版本有兼容问题锁定Linux内核同样用第3节的方法逻辑完全一致。写到这里修改GRUB默认启动内核的几种方案、底层原理和常见坑基本都覆盖到了。我个人在实际操作中的体会是能靠菜单项名称锁定就尽量别用序号能分清楚永久修改和单次切换这两类需求就不会在GRUB配置上反复折腾。最后再分享一个小技巧每次update-grub之后随手执行一下grep menuentry /boot/grub/grub.cfg扫一眼菜单顺序几秒钟的功夫能避免很多次重启后才发现选错内核的尴尬。这个事儿多操作两次就熟了剩下的就是自己动手试一次。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询