尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Ubuntu切换默认内核版本:Grub配置全流程实操指南
1. 先搞清楚你为什么要改默认内核版本说句实在话正常人不会闲着没事去折腾默认启动的内核。会出现这个需求基本就是下面这几个场景系统自动更新把内核升到了新版本结果重启之后某个硬件驱动不正常了。常见的就是WiFi网卡掉线、声卡没声音、NVIDIA显卡驱动加载失败甚至直接卡在开机界面。你需要用的某个内核模块或者实时补丁比如在某些工控场景下用带RT补丁或者特定驱动支持的内核版本只有某一个特定版本的内核才带对应的支持新内核反而把配置改了。你在做内核开发或者内核调试需要在多个版本之间来回切换默认进哪个版本必须自己说了算。装完双系统之后grub默认进的是Ubuntu某个不稳定的内核想快速回退到之前稳定运行的版本。以上无论哪种情况本质上都是在跟grub打交道。grub就是开机时那个让你选系统的引导菜单它决定了解压哪一个内核、挂载哪一个根文件系统。Ubuntu默认把grub的配置文件放在/boot/grub/grub.cfg但这个文件不让你直接改——Ubuntu的做法是让你修改/etc/default/grub和/etc/grub.d/下的脚本然后执行update-grub来重新生成 grub.cfg。这一层封装让很多人摸不着头脑我明明改了配置文件怎么重启之后没变化这篇内容就是把整个切换内核版本的流程彻底掰开揉碎从查看当前内核、定位grub菜单项名称、手动应急切换到永久修改默认启动项再到常见的坑一条线讲完。既适合刚入门、连grub菜单都找不到的朋友也适合已经踩过一些坑、想搞清楚原理的老手。2. 动手前必须掌握的三个基础概念2.1 /boot 目录里到底装了什么先看一眼你的系统里有哪些内核。执行dpkg --list | grep linux-image输出大致长这样ii linux-image-5.15.0-91-generic 5.15.0-91.101 amd64 Signed kernel image generic ii linux-image-5.15.0-92-generic 5.15.0-92.102 amd64 Signed kernel image generic ii linux-image-6.2.0-26-generic 6.2.0-26.26 amd64 Signed kernel image generic每一行代表系统里已经安装的一个内核版本。正常情况下Ubuntu会保留两到三个版本防止最新版出问题没法回退。再执行uname -r查看当前正在运行的内核版本。注意这个命令显示的才是“你正在用的”那个内核可能跟grub默认启动的内核不是同一个——有时候你手动从grub菜单选了老版本启动但系统里默认项还是新版本。2.2 grub菜单项和内核版本不是一一对应的很多人第一个误区是以为grub菜单里每一个“Ubuntu”选项对应一个内核版本。实际上grub菜单结构是被组织成多级菜单的。正常安装的Ubuntu开机grub界面会显示两项UbuntuAdvanced options for Ubuntu“Advanced options for Ubuntu”里才会列出所有内核版本。每一个版本又细分两个选项普通模式就是正常启动和恢复模式recovery mode带一个精简的initramfs主要用于修复系统。所以你要内核版本真正要定位的是“Advanced options for Ubuntu”下面的子菜单项。2.3 grub.cfg由脚本生成不直接编辑/boot/grub/grub.cfg是最终被grub读取的配置文件但每次你执行update-grub它都会根据/etc/default/grub和/etc/grub.d/目录下的脚本重新生成一遍。直接编辑 grub.cfg 的后果就是在下次 update-grub 之后所有手动修改全部被覆盖。所以正确的工作流是修改/etc/default/grub里的 GRUB_DEFAULT 等配置项执行sudo update-grub让配置写入 grub.cfg重启生效。后面的所有操作都围绕这个流程。3. 第一步定位你想要的菜单项名称和顺序3.1 用 grep 直接查看grub菜单里的全部选项执行这条命令查看当前grub菜单里所有可选的启动项grep -E menuentry |submenu /boot/grub/grub.cfg输出类似menuentry Ubuntu --class ubuntu ... submenu Advanced options for Ubuntu ... menuentry Ubuntu with Linux 5.15.0-91-generic ... menuentry Ubuntu with Linux 5.15.0-91-generic (recovery mode) ... menuentry Ubuntu with Linux 5.15.0-92-generic ... menuentry Ubuntu with Linux 5.15.0-92-generic (recovery mode) ... menuentry Ubuntu with Linux 6.2.0-26-generic ... menuentry Ubuntu with Linux 6.2.0-26-generic (recovery mode) ... menuentry Windows Boot Manager ...这个列表就是你grub菜单的真实结构。注意标题里的逗号后面是有空格的“Ubuntu, with Linux ...”在配置 GRUB_DEFAULT 时要照抄不能去掉空格。3.2 搞清楚grub启动项的编号方式grub的启动项编号从0开始按照菜单从上到下的顺序排列。以上面的输出为例编号菜单项0Ubuntu1Advanced options for Ubuntu (展开前的submenu)2第一个内核版本普通模式3第一个内核版本恢复模式4第二个内核版本普通模式… 以此类推注意这里列出的编号是直接把子菜单项平铺计算的结果但实际使用中如果你要指定子项内部的某个项不能直接写这个平铺的编号而要采用子菜单编号子菜单内部编号的写法。比如10表示“Advanced options for Ubuntu”里的第一项也就是 5.15.0-91-generic 普通模式。这种写法对应的是“先进顶级菜单再进子菜单”的路径方式是grub里定位嵌套菜单的标准方式。后面配置 GRUB_DEFAULT 时会用到。3.3 怎么看当前默认启动项grub-editenv这个命令可以查看grub环境变量默认启动项信息也存在这里sudo grub-editenv list输出中的saved_entry字段只在配置了GRUB_DEFAULTsaved时才会生效。如果你没特别设置过默认的保存项是空的grub就直接使用 GRUB_DEFAULT 里写的数字或菜单名字符串。4. 临时应急只改本次启动的内核在正式修改默认配置之前强烈建议先做一次手动验证从grub菜单里临时选一次目标内核启动确认这个内核确实能正常进系统、驱动和模块都没问题再去修改默认配置。否则直接改了默认项结果目标内核根本没发正常启动反而进不了系统这就尴尬了。4.1 开机呼出grub菜单Ubuntu 18.04之后的版本默认grub菜单是隐藏的开机时只显示一个Ubuntu的logo不会自动弹出菜单。要手动呼出菜单需要在BIOS自检结束、屏幕刚有显示的时候长按Shift键BIOS引导方式或者连续按Esc键UEFI引导方式。看到grub菜单之后选择“Advanced options for Ubuntu”回车进入子菜单然后用方向键选中你要的内核版本回车启动。4.2 用 grub-reboot 实现临时切换如果你不想重启时手动去按键盘也可以用grub-reboot命令实现“单次启动使用指定内核下次重启自动恢复默认项”sudo grub-reboot Advanced options for UbuntuUbuntu with Linux 5.15.0-91-generic这条命令的本质是设置一个一次性环境变量grub在下次启动时会优先读取这个变量对应的菜单项启动完成后自动清除。先验证、再固化这个顺序能帮你避开“改完默认项却发现根本启动不了”的坑。我真的是见过有人在grub.cfg上把默认项直接指向了一个内核重启后直接黑屏最后只能进恢复模式改回来。5. 永久修改默认启动内核三种方案对比方案没有绝对的好坏关键是看你想要什么效果。下面三种都实测过适用场景不同。5.1 直接改 GRUB_DEFAULT 为子菜单路径编辑/etc/default/grubsudo nano /etc/default/grub找到这一行GRUB_DEFAULT0改成子菜单路径的写法GRUB_DEFAULTAdvanced options for UbuntuUbuntu with Linux 5.15.0-91-generic符号前后不要加空格整个值用双引号包起来。保存之后执行sudo update-grub重启之后生效。这种方式的优点是直观、明确、不怕内核顺序变化。你指定的是菜单项的完整标题字符串哪怕你后来又装了几个新内核只要目标内核没被删掉它还是默认启动项。缺点是字符串比较长而且如果系统locale是中文update-grub生成的首级菜单标题可能会变成“Ubuntu的高级选项”那你就得写中文标题容易出现编码问题。后面专门讲这个坑。5.2 用 grub-set-default 配合 GRUB_DEFAULTsaved如果你不想直接改配置文件grub也提供了一套运行时管理命令。思路是让grub从“保存的启动项”读取默认项然后通过grub-set-default修改保存的值。第一步修改/etc/default/grubGRUB_DEFAULTsaved然后执行sudo update-grub。第二步查看所有菜单项编号然后设置默认项为某个序号。比如顶级菜单第2项sudo grub-set-default 2这里的编号是顶级菜单的编号。如果你的目标内核在子菜单里grub-set-default不能直接设置子项必须使用菜单项标题字符串而且写法同样是子菜单子项。比如sudo grub-set-default Advanced options for UbuntuUbuntu with Linux 5.15.0-91-generic设置完之后可以通过下面的命令验证sudo grub-editenv list会输出saved_entry...内容和刚才设置的一样。这种方式的优势是不需要反复编辑配置文件可以在系统运行中灵活修改脚本化操作友好。特别是在调试脚本的时候比改文件再update-grub再重启的要轻量很多。5.3 让grub记住你最后一次选择的启动项还有一种更“傻瓜”的方案——让grub记住你上次手动选择的是哪一项。修改/etc/default/grubGRUB_DEFAULTsaved GRUB_SAVEDEFAULTtrue加第一行表示默认项从saved_entry环境变量读取加第二行表示每次启动时如果你是手动选择了某个菜单项grub会把这个选择自动记录到saved_entry作为下次的默认项。这种方式适合你经常手动切换内核的场景。比如今天用5.15干活明天切6.2测新特性每次开机手动选一下下次启动就记住你上次的选择。它的规则是“跟随上次的选择”而不是“固定的某个版本”别搞混了。5.4 三方案对比总结方案操作复杂度适用场景注意事项修改GRUB_DEFAULT为完整标题低固定使用某内核长期不变标题字符串要和grub.cfg完全一致grub-set-default结合saved中服务器远程管理脚本化切换子菜单项需用完整标题不能用数字GRUB_SAVEDEFAULTtrue低经常手动切换内核的测试机每次手动选择会覆盖之前的默认项从稳定性和可维护性角度我个人最推荐第一种直接写完整标题字符串。因为它的配置项是自解释的几个月后你回头看/etc/default/grub一眼就能看出系统默认启动的是哪个内核。用数字编号的话你自己都记不住编号对应哪个菜单项。6. 核心细节为什么不能只改数字编号很多人会想既然grub菜单项从上往下是从0开始编号的那我直接写 GRUB_DEFAULT4 不就行了为什么还要写那么长的标题理论上可以gurb确实支持数字编号。但你注意一个问题菜单项的顺序不是永久的。系统升级安装新内核后新内核会排在最前面你的数字编号就错位了。假设你现在编号2是 5.15.0-91升级内核后编号2变成了6.2.0-27系统默认启动项就变成了另一个内核这种隐性变化很难第一时间发现。而用标题字符串匹配grub启动时会按标题内容去查找菜单项找到就启动找不到就用默认编号0不会错位。数字编号适合你的目标内核恰好是第一项的情况其余场景一律推荐完整标题字符串。还有一个细节grub的菜单项标题匹配是“子串匹配”也就是说GRUB_DEFAULT5.15.0-91也能匹配到Ubuntu with Linux 5.15.0-91-generic。但我不推荐用这种简写因为存在一个隐患如果同时存在Ubuntu with Linux 5.15.0-91-generic和Ubuntu with Linux 5.15.0-91-generic (recovery mode)它匹配到的是排在前面的普通模式这一点还算可控。但如果你有多个同前缀的菜单项grub取第一个匹配到的你没法确定就是你要的那个。所以要用就用完整标题别偷懒。7. 进阶submenu 的特殊处理7.1 为什么有的系统没有submenu有些精简过的Ubuntu系统或者通过某些工具定制过的grub配置会把所有内核版本直接平铺在顶级菜单没有“Advanced options for Ubuntu”这个子菜单。这种情况下菜单项编号就是平铺的直接用数字或者完整标题都可以。判断方式很简单看你/boot/grub/grub.cfg里有没有submenu关键字。有就是带子菜单的结构没有就是平铺结构。7.2 从子菜单切回顶级菜单如果你设置了状态默认项是子菜单里的某个内核但有天想切回顶级菜单的“Ubuntu”标准项只要把 GRUB_DEFAULT 改成0或者Ubuntu再 update-grub 即可。进入子菜单之后怎么回到顶级菜单不需要额外的配置因为你设置的是绝对路径10是子项路径0是顶级路径互不干扰。7.3 子菜单里恢复模式的特别提醒子菜单里每个内核版本后面会有一个(recovery mode)的项这个不要作为默认启动项用。恢复模式会加载一个精简的initramfs跳过很多正常启动服务用于修复系统不适合日常使用。如果你在写 GRUB_DEFAULT 的时候不小心复制了带(recovery mode)的标题系统启动后你会直接进到一个只有root shell的恢复界面很容易以为自己系统坏了。其实只是选错了启动项。8. 如何安全地删除不需要的内核版本当你的/boot分区空间不足或者确定某个内核不会再使用了可以考虑删除旧内核释放空间。删除之前必须明确一个底线不要删除当前正在运行的内核。万一grub配置出现问题你还能用当前内核启动找回之前的配置。查看当前内核uname -r列出所有已安装内核dpkg --list | grep linux-image删除指定内核以5.15.0-91-generic为例sudo apt purge linux-image-5.15.0-91-generic linux-headers-5.15.0-91-generic执行完成后会自动跑一遍update-grub菜单里的对应项会自动消失。注意内核的headers包编译内核模块时需要和image包是分开的建议一起删除不然/usr/src下面会残留一堆没用的头文件。这里我能给的实用建议是保留最近的两个内核别贪多也别全删。万一你用的新内核有未知bug至少还有一个备用内核能顶上。我见过有人为了省磁盘空间把所有老内核都删了结果最新的内核直接挂掉系统都进不去最后只能靠live CD修复得不偿失。9. 踩坑记录修改内核版本时的常见问题下面这些坑我自己踩过一部分群友踩过另一部分都很典型列出来给你们排雷。9.1 改了GRUB_DEFAULT但重启没生效现象改完/etc/default/grub重启后进的内核还是原来那个。排查顺序你执行sudo update-grub了吗只有执行了才会把配置写入 grub.cfg这一步很多人会忘。执行后/boot/grub/grub.cfg里set default的值是什么可以grep确认一下grep set default /boot/grub/grub.cfg如果是一个被解析过的值说明配置已经生效问题可能出在菜单标题没匹配上。如果还是0说明/etc/default/grub里的配置是错的。你的默认项是“saved”吗如果你设置了GRUB_DEFAULTsaved但/boot/grub/grub.cfg里没有对应的 saved_env 配置grub可能会回退到第一项。9.2 用中文标题匹配失败如果你的系统locale是中文Ubuntu执行update-grub时会把菜单项的显示文本按当前locale处理。比如menuentry Ubuntu with Linux 5.15.0-91-generic在中文环境里可能变成“Ubuntu包含Linux 5.15.0-91-generic”之类的标题而你/etc/default/grub里写的是英文标题最终grub匹配不到菜单项回退到默认第0项。解决办法有两个执行sudo update-grub时指定英文localesudo LANGC update-grub生成的 grub.cfg 里菜单项保持英文标题。配置 GRUB_DEFAULT 时用数字编号绕开标题匹配。第一种方式更干净推荐优先使用。9.3 grub启动时进到 grub 命令行这是grub minimal bash like line editing is supported故障本质上是因为grub找不到配置文件或者配置损坏。原因可能是分区布局变化比如重装了Windows导致EFI分区变化/boot/grub/grub.cfg丢失或文件系统损坏手动改坏了/etc/default/grub导致update-grub生成无效配置。如果你遇到这个问题先手动输入下面几条命令尝试启动系统set root(hd0gpt2) linux /vmlinuz-5.15.0-91-generic root/dev/sda2 initrd /initrd.img-5.15.0-91-generic boot这里hd0gpt2是/boot分区的位置/dev/sda2是根分区要根据你的实际分区调整。能进系统之后立即重新执行sudo update-grub修复配置。9.4 /boot空间满了导致update-grub失败现象执行 update-grub 时报磁盘空间不足错误或者生成的 grub.cfg 不完整。原因/boot分区是独立的容量通常只有1G左右。内核和initramfs文件加起来每一个都有几十MB几个版本就把空间占满了。处理方式删掉旧内核释放空间后再执行 update-grub。方法参考第8节。9.5 设置默认启动Windows而不是Ubuntu如果你装的是双系统想改默认启动WindowsGRUB_DEFAULT 写成GRUB_DEFAULTWindows Boot Manager或者执行sudo grub-set-default Windows Boot ManagerWindows的菜单项标题可能因机器而异先执行grep menuentry /boot/grub/grub.cfg确认准确标题再配置。10. 实操心得我自己用的完整流程到这里整个改默认内核版本的原理和操作都讲完了。最后分享一下我个人在实操中最常用的一套流程你可以直接照搬先dpkg --list | grep linux-image确认已安装的内核版本列表执行grep -E menuentry |submenu /boot/grub/grub.cfg手动查看grub菜单项完整标题临时用sudo grub-reboot Advanced options for UbuntuUbuntu with Linux 5.15.0-91-generic启动目标内核确认驱动、模块、桌面环境一切正常确认无误后把GRUB_DEFAULT修改为对应完整标题执行sudo LANGC update-grub生成配置文件重启验证。这个顺序里最关键的就是第3步的“先验证再固化”。我在处理线上服务器的时候从不跳过这一步。正是因为有过直接改默认项结果把系统改挂的教训才养成了每次都要先做一次性启动验证的习惯。另外在/etc/default/grub里保留注释是个好习惯。我会在修改过的地方加上类似# default kernel 5.15.0-91 for ethercat igc support的说明标注当时改这个配置的原因避免一段时间后自己都忘了当初为什么选这个版本。grub这块操作虽然看起来命令不多但牵一发动全身每一步都值得确认清楚再动手。希望这篇文章能帮你一次就把默认内核版本切换搞定别再被重启后“进错系统”这种事折腾。
RELATED

相关推荐

Monty 沙箱文件系统挂载深度解析:monty-fs 的 MountTable 与结构化沙箱边界

Monty 沙箱文件系统挂载深度解析:monty-fs 的 MountTable 与结构化沙箱边界

Monty 沙箱文件系统挂载深度解析:monty-fs 的 MountTable 与结构化沙箱边界 【免费下载链接】monty A minimal, secure Python interpreter written in Rust for use by AI 项目地址: https://gitcode.com/GitHub_Trending/monty3/monty 本篇技术指南聚焦 Mo…

📅 2026/9/16 21:54:52
Python文件操作三剑客:os、pathlib与shutil实战指南

Python文件操作三剑客:os、pathlib与shutil实战指南

1. Python文件系统操作基础指南在Python开发中,文件系统操作是最基础也是最高频使用的功能之一。无论是数据分析师需要读取CSV文件,还是后端工程师处理上传的图片,亦或是自动化脚本整理下载目录,都离不开对文件和目录的操作。Pyth…

📅 2026/9/16 21:54:52
Outlook日历三端同步全攻略:Win10/安卓/iOS无缝衔接

Outlook日历三端同步全攻略:Win10/安卓/iOS无缝衔接

前阵子我碰到一个让我头疼了半天的问题:电脑上新建了一条会议,Windows 10 的 Outlook 里显示下午三点;我顺手用 Android 手机改了时间,手机上变成四点;结果回到电脑前,桌面客户端还是下午三点。同一个日历&…

📅 2026/9/16 21:54:52
MORE NEWS

更多资讯

📰

360°视频编码测试条件与参考配置全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Transformer电价预测实战:从注意力机制到超长序列建模

电价预测这事,圈子里常年是“长短期记忆模型”和“梯度提升树”的天下,大家默认时序问题就该这么解。但这两年有个很明显的变化:原本在自然语言处理领域称王的Transformer架构,开始被越来越多人拿来试水电价、负荷这类强波动时序数…

📰

VSCode搭建Arduino UNO开发环境:代码补全与编译烧录全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

攻击流量样本分析实战:从PCAP捕获到威胁狩猎与检测规则落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

ESP32音频开发实战:I2S+WAV+MicroPython零基础入门

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

高通Camx相机调试:UMD/KMD日志开关、图像Dump与离线合成实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬