当前位置: 代码网 > 服务器>服务器>Linux > Linux内核升级后启动失败的解决方案

Linux内核升级后启动失败的解决方案

2026年07月27日 Linux 我要评论
前言ubuntu 更新内核后无法启动,最稳妥的处理方式不是马上删内核、重装驱动或反复强制关机,而是先保留一条能进入系统的路径。这一篇主要处理旧内核仍然可以启动的情况。内容从启动链定位开始,依次检查失败

前言

ubuntu 更新内核后无法启动,最稳妥的处理方式不是马上删内核、重装驱动或反复强制关机,而是先保留一条能进入系统的路径。

这一篇主要处理旧内核仍然可以启动的情况。内容从启动链定位开始,依次检查失败日志、包管理状态、/boot 空间、initramfs、根文件系统 uuid、grub 参数、dkms 与 secure boot。

处理原则:先用旧内核恢复可操作环境,再根据证据修复新内核。旧内核在新内核完成验证前不要删除。

本文重点解决以下问题:

  • 新内核启动失败后,怎样从 grub 进入旧内核;
  • 怎样判断故障发生在 grub、内核、initramfs 还是驱动阶段;
  • 怎样重建指定内核的 initramfs 和 grub;
  • 怎样核对 uuid、fstabroot= 启动参数;
  • 怎样处理 dkms、headers 与 secure boot 导致的模块故障。

一、先看懂启动链:报错出现在哪一层

ubuntu 从按下电源到进入桌面,大致会经历下面几个阶段:

启动阶段主要工作常见故障表现
uefi/bios初始化硬件并寻找启动项找不到启动盘、没有 ubuntu 启动项
grub显示内核菜单并传递启动参数grub 菜单消失、菜单损坏、选项错误
linux kernel初始化 cpu、内存和基础设备选择内核后立刻重启、kernel panic
initramfs加载早期驱动并找到根文件系统掉进 (initramfs)、找不到 uuid、无法挂载根分区
根文件系统与 systemd挂载磁盘、启动服务emergency mode、fstab 挂载失败
驱动与桌面加载显卡、网卡和外部模块黑屏、无线网卡消失、virtualbox/nvidia 模块不可用

先判断失败阶段,再决定使用什么工具。

  • grub 没有菜单:检查 uefi 启动项和 grub;
  • 进入 (initramfs):优先检查根分区、uuid、存储驱动和 initramfs;
  • 进入 emergency mode:重点查看 /etc/fstab 和 systemd 失败单元;
  • 桌面前黑屏:再考虑显卡模块、显示管理器和 nomodeset
  • 新内核下网卡或虚拟化模块消失:检查 dkms、headers 和 secure boot。

这一步看似简单,却能避免后面大量无效操作。

二、旧内核能启动,就先从旧内核进入系统

2.1 调出 grub 菜单

传统 bios 机器开机时可以尝试按住 shift,uefi 机器通常连续按 esc。不同电脑的固件启动速度不同,按键时机可能需要试几次。

进入 grub 后选择:

advanced options for ubuntu

一般可以看到新旧内核及其 recovery mode,例如:

  • ubuntu, with linux 6.x.y-new-generic
  • ubuntu, with linux 6.x.y-new-generic (recovery mode)
  • ubuntu, with linux 6.x.y-old-generic
  • ubuntu, with linux 6.x.y-old-generic (recovery mode)

先选择旧内核的普通启动项。只要旧内核还能进入系统,后面的检查和修复都会轻松很多。

2.2 确认当前真正运行的内核

进入系统后先执行:

uname -r

不要只看 grub 菜单里选了哪个,uname -r 才是当前真正运行的版本。

查看系统中已经安装的内核包:

dpkg -l 'linux-image-*' | grep '^ii'

再检查 /boot 中的新旧内核文件是否都存在:

ls -lh /boot

重点关注:

  • vmlinuz-<version>:内核镜像;
  • initrd.img-<version>:对应的 initramfs;
  • config-<version>:内核配置;
  • system.map-<version>:符号映射信息。

2.3 暂时不要删除旧内核

旧内核现在不是“占空间的旧文件”,而是系统最重要的恢复入口。

至少满足下面条件后,再考虑清理:

  • 新内核已经连续正常启动;
  • 网络、显卡、磁盘和虚拟化模块正常;
  • dkms status 没有异常;
  • grub 中仍能看到可靠的回退项;
  • /boot 和根文件系统没有错误。

执行自动清理前先看模拟结果:

sudo apt autoremove --dry-run

确认不会删除当前运行内核和唯一可用的旧内核后,再决定是否执行:

sudo apt autoremove

不要在唯一能够启动的内核上做“自动清理实验”。

三、先留证据:不要只盯着最后一屏报错

3.1 查看启动历史

在旧内核中执行:

journalctl --list-boots

输出会列出最近几次启动记录。当前启动通常是 0,上一次是 -1,再上一次是 -2

查看上一次启动的内核日志:

sudo journalctl -b -1 -k

只看错误级别:

sudo journalctl -b -1 -p err

搜索常见关键字:

sudo journalctl -b -1 -k | grep -ei \
'panic|error|fail|timeout|nvme|ata|ext4|xfs|btrfs|firmware|nvidia|dkms'

如果故障发生得太早,系统可能还没来得及把日志写进 journal。此时屏幕报错、initramfs shell 中的输出、云服务器串口日志同样重要。

3.2 用当前正常启动作为对照

查看当前旧内核的启动信息:

sudo dmesg -t | less

重点观察存储、根分区、固件和模块:

sudo dmesg -t | grep -ei \
'nvme|ata|root|firmware|module|secure|iommu'

旧内核能识别、而新内核识别不到的设备,往往就是问题线索。

3.3 检查包管理是否中断

内核升级过程中断电、网络异常或磁盘写满,都可能留下“包已经解压,但还没有配置完成”的状态。

先检查:

sudo dpkg --audit

继续处理未完成配置:

sudo dpkg --configure -a

修复依赖:

sudo apt-get -f install

执行需要下载软件包的命令前,先确认网络和软件源可用。

3.4 检查/boot和根分区空间

/boot 空间不足是内核升级失败的高频原因。系统可能已经安装了新内核包,却没能完整生成 initramfs。

df -h /boot /

再检查 inode:

df -i /boot /

如果更新过程中出现:

no space left on device

不要只看 / 的剩余空间。单独挂载的 /boot 可能已经满了。

排查到这里时,先别急着重建所有东西。先确认磁盘空间、包状态和新内核目录完整,否则后面的 update-initramfs 仍会失败。

四、重建新内核的 initramfs 和 grub

4.1 initramfs 到底负责什么

内核刚开始运行时,真正的根文件系统还没有挂载。initramfs 是一套临时的早期用户空间,里面通常包含:

  • 找到磁盘所需的存储驱动;
  • lvm、raid、luks 等工具;
  • 根文件系统驱动;
  • 挂载根分区所需脚本;
  • 把启动过程切换到真正根文件系统的逻辑。

如果 nvme、ahci、virtio、lvm、加密卷或文件系统驱动没有正确进入 initramfs,就可能出现:

gave up waiting for root file system device
alert! uuid=... does not exist
kernel panic - not syncing: vfs: unable to mount root fs

4.2 确认目标内核版本

查看模块目录:

ls /lib/modules

假设故障内核是 6.x.y-new-generic,可以先设置变量:

new_kernel='6.x.y-new-generic'

检查目录是否存在:

test -d "/lib/modules/$new_kernel" && echo "modules directory exists"

再检查内核与 initrd:

ls -lh "/boot/vmlinuz-$new_kernel" \
       "/boot/initrd.img-$new_kernel"

4.3 更新或重新创建 initramfs

更新已有 initramfs:

sudo update-initramfs -u -k "$new_kernel"

如果对应 initrd 根本不存在,可以创建:

sudo update-initramfs -c -k "$new_kernel"

-u 是更新,-c 是创建。不要为了“重来一次”直接手工删除 /boot/initrd.img-*,否则包管理状态和实际文件更容易对不上。

完成后检查:

ls -lh "/boot/initrd.img-$new_kernel"

4.4 查看 initramfs 里有没有关键模块

lsinitramfs "/boot/initrd.img-$new_kernel" | less

搜索常见存储、加密和 lvm 组件:

lsinitramfs "/boot/initrd.img-$new_kernel" \
  | grep -ei 'nvme|ahci|virtio|dm-crypt|cryptsetup|lvm'

这里不能仅凭“没搜到一个名字”就认定模块缺失。某些驱动可能直接编进内核,文件名也可能和预期不同。更可靠的做法是对比:

lspci -k

以及旧内核对应 initramfs 的内容。

4.5 重新生成 grub 菜单

sudo update-grub

正常情况下会看到类似输出:

found linux image: /boot/vmlinuz-...
found initrd image: /boot/initrd.img-...

如果只找到内核镜像,却没有对应 initrd,应先回头解决 initramfs 生成错误。

五、检查根文件系统 uuid、fstab 和启动参数

5.1 核对真实 uuid

lsblk -f

或者:

sudo blkid

查看系统配置:

cat /etc/fstab

重点核对:

  • 根分区 /
  • /boot
  • /boot/efi
  • swap 或 resume= 对应分区;
  • 额外数据盘。

uuid 发生变化的常见原因包括克隆磁盘、恢复快照、重建文件系统、调整 lvm、替换硬盘和手工改分区。

尽量不要在 fstab 中长期写死 /dev/sdax/dev/nvme0n1px设备枚举顺序变化后,名称可能改变,而 uuid 通常更稳定。

5.2 检查 grub 传递的root=

grep -n "linux.*root=" /boot/grub/grub.cfg | head

grub.cfg 一般由工具生成,不建议直接长期手改。应修正 /etc/default/grub/etc/fstab 或相关脚本,再执行:

sudo update-grub

5.3 在 grub 中临时修改参数

在 grub 菜单选中启动项后按 e,找到以 linux 开头的一行。

常用的临时诊断操作:

  • 删除 quiet splash,直接观察详细启动日志;
  • 加入 nomodeset,判断是否卡在显卡模式设置;
  • 检查 root=uuid=... 是否与真实根分区一致;
  • 检查错误的 resume=、iommu、模块黑名单或显卡参数。

临时修改只对本次启动有效,不会自动写回配置。

nomodeset 适合帮助进入系统和判断问题方向,但它通常不是显卡问题的最终解决方案。

六、dkms:为什么新内核装好了,驱动却没跟上

6.1 dkms 模块与内核版本绑定

nvidia、virtualbox、zfs 以及部分网卡驱动使用 dkms。它们并不是跟着内核镜像天然存在,而是要针对每一个内核版本单独构建模块。

检查状态:

dkms status

可能看到:

module/version, old-kernel, installed
module/version, new-kernel, added

addedbuiltinstalled 不是一回事。要让新内核正常使用该模块,目标版本通常需要达到 installed 状态。

6.2 检查 dkms 构建日志

日志一般位于:

/var/lib/dkms/<module>/<version>/build/make.log

查找所有日志:

sudo find /var/lib/dkms -name make.log -type f -print

查看最近错误:

sudo tail -n 120 \
  /var/lib/dkms/<module>/<version>/build/make.log

常见原因:

  • 没安装新内核 headers;
  • 驱动版本不兼容新的内核 api;
  • 编译器版本或构建环境不匹配;
  • secure boot 阻止未签名模块;
  • /boot/var 空间不足;
  • 包配置流程中断。

6.3 安装 headers 并重新构建

检查 headers:

dpkg -l "linux-headers-$new_kernel"

缺少时安装:

sudo apt install "linux-headers-$new_kernel"

重新构建:

sudo dkms autoinstall -k "$new_kernel"

完成后重建 initramfs 和 grub:

sudo update-initramfs -u -k "$new_kernel"
sudo update-grub

6.4 secure boot 也可能让模块“存在但加载失败”

查看状态:

mokutil --sb-state

查看内核日志:

sudo dmesg | grep -ei \
'secure boot|verification failed|module verification'

模块文件已经生成,却仍然无法加载,不一定是编译失败,也可能是签名和信任链问题。

关闭 secure boot 不是唯一答案。更合适的方案取决于机器的安全要求、驱动来源以及 mok 签名流程。

总结

旧内核还能启动时,修复条件其实很好:系统文件、日志和包管理工具都还能正常使用。此时不要急着删除新内核,也不要把所有修复命令一起执行。

更稳的顺序是:

旧内核进入系统 → 保存失败日志 → 检查包与磁盘空间 → 重建 initramfs → 核对 uuid 和 grub 参数 → 修复 dkms → 再测试新内核

完成修复后,至少保留一个已经验证可启动的旧内核。假如旧内核、普通模式和桌面环境都无法进入,就需要转向 initramfs shell、recovery mode 或 live usb + chroot,具体操作放在下篇。

以上就是linux内核升级后启动失败的解决方案的详细内容,更多关于linux内核升级后启动失败的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com