Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > Linux内核升级后启动失败

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

作者:爱和冰阔落

Ubuntu 更新内核后无法启动,最稳妥的处理方式不是马上删内核、重装驱动或反复强制关机,而是先保留一条能进入系统的路径,这一篇主要处理旧内核仍然可以启动的情况,需要的朋友可以参考下

前言

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

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

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

本文重点解决以下问题:

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

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

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

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

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

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

2.1 调出 GRUB 菜单

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

进入 GRUB 后选择:

Advanced options for Ubuntu

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

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

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

进入系统后先执行:

uname -r

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

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

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

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

ls -lh /boot

重点关注:

2.3 暂时不要删除旧内核

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

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

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

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 是一套临时的早期用户空间,里面通常包含:

如果 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

重点核对:

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 开头的一行。

常用的临时诊断操作:

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

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

常见原因:

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内核升级后启动失败的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文