【Linux】内核升级后启动失败?旧内核回退、initramfs 重建与 DKMS 修复
2026/7/27 5:11:35 网站建设 项目流程

🔥个人主页:爱和冰阔乐
📚专栏传送门:《数据结构与算法》 、C++
🐶学习方向:C++方向学习爱好者
⭐人生格言:得知坦然 ,失之淡然


🏠博主简介

文章目录

  • 前言
  • 一、先看懂启动链:报错出现在哪一层
  • 二、旧内核能启动,就先从旧内核进入系统
    • 2.1 调出 GRUB 菜单
    • 2.2 确认当前真正运行的内核
    • 2.3 暂时不要删除旧内核
  • 三、先留证据:不要只盯着最后一屏报错
    • 3.1 查看启动历史
    • 3.2 用当前正常启动作为对照
    • 3.3 检查包管理是否中断
    • 3.4 检查 `/boot` 和根分区空间
  • 四、重建新内核的 initramfs 和 GRUB
    • 4.1 initramfs 到底负责什么
    • 4.2 确认目标内核版本
    • 4.3 更新或重新创建 initramfs
    • 4.4 查看 initramfs 里有没有关键模块
    • 4.5 重新生成 GRUB 菜单
  • 五、检查根文件系统 UUID、fstab 和启动参数
    • 5.1 核对真实 UUID
    • 5.2 检查 GRUB 传递的 `root=`
    • 5.3 在 GRUB 中临时修改参数
  • 六、DKMS:为什么新内核装好了,驱动却没跟上
    • 6.1 DKMS 模块与内核版本绑定
    • 6.2 检查 DKMS 构建日志
    • 6.3 安装 headers 并重新构建
    • 6.4 Secure Boot 也可能让模块“存在但加载失败”
  • 总结
  • 参考资料

前言

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 Linux6.x.y-new-generic
  • Ubuntu, with Linux6.x.y-new-generic (recovery mode)
  • Ubuntu, with Linux6.x.y-old-generic
  • Ubuntu, with Linux6.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和根文件系统没有错误。

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

sudoaptautoremove --dry-run

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

sudoaptautoremove

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


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

3.1 查看启动历史

在旧内核中执行:

journalctl --list-boots

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

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

sudojournalctl-b-1-k

只看错误级别:

sudojournalctl-b-1-perr

搜索常见关键字:

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

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

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

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

sudodmesg-T|less

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

sudodmesg-T|grep-Ei\'nvme|ata|root|firmware|module|secure|iommu'

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

3.3 检查包管理是否中断

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

先检查:

sudodpkg--audit

继续处理未完成配置:

sudodpkg--configure-a

修复依赖:

sudoapt-get-finstall

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

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:

sudoupdate-initramfs-u-k"$NEW_KERNEL"

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

sudoupdate-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 菜单

sudoupdate-grub

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

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

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


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

5.1 核对真实 UUID

lsblk-f

或者:

sudoblkid

查看系统配置:

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或相关脚本,再执行:

sudoupdate-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

查找所有日志:

sudofind/var/lib/dkms-namemake.log-typef-print

查看最近错误:

sudotail-n120\/var/lib/dkms/<module>/<version>/build/make.log

常见原因:

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

6.3 安装 headers 并重新构建

检查 headers:

dpkg-l"linux-headers-$NEW_KERNEL"

缺少时安装:

sudoaptinstall"linux-headers-$NEW_KERNEL"

重新构建:

sudodkms autoinstall-k"$NEW_KERNEL"

完成后重建 initramfs 和 GRUB:

sudoupdate-initramfs-u-k"$NEW_KERNEL"sudoupdate-grub

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

查看状态:

mokutil --sb-state

查看内核日志:

sudodmesg|grep-Ei\'secure boot|verification failed|module verification'

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

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



总结

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

更稳的顺序是:

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

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


参考资料

  1. Ubuntu Kernel:https://ubuntu.com/kernel
  2. Ubuntu GRUB 2:https://help.ubuntu.com/community/Grub2
  3. update-initramfs手册:https://manpages.ubuntu.com/manpages/jammy/en/man8/update-initramfs.8.html
  4. DKMS:https://github.com/dell/dkms
  5. Linux Kernel initrd:https://docs.kernel.org/admin-guide/initrd.html

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询