【Linux】内核升级后启动失败?旧内核回退、initramfs 重建与 DKMS 修复

【Linux】内核升级后启动失败?旧内核回退、initramfs 重建与 DKMS 修复 个人主页爱和冰阔乐专栏传送门《数据结构与算法》 、C学习方向C方向学习爱好者⭐人生格言得知坦然 失之淡然博主简介文章目录前言一、先看懂启动链报错出现在哪一层二、旧内核能启动就先从旧内核进入系统2.1 调出 GRUB 菜单2.2 确认当前真正运行的内核2.3 暂时不要删除旧内核三、先留证据不要只盯着最后一屏报错3.1 查看启动历史3.2 用当前正常启动作为对照3.3 检查包管理是否中断3.4 检查 /boot 和根分区空间四、重建新内核的 initramfs 和 GRUB4.1 initramfs 到底负责什么4.2 确认目标内核版本4.3 更新或重新创建 initramfs4.4 查看 initramfs 里有没有关键模块4.5 重新生成 GRUB 菜单五、检查根文件系统 UUID、fstab 和启动参数5.1 核对真实 UUID5.2 检查 GRUB 传递的 root5.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、fstab与root启动参数怎样处理 DKMS、headers 与 Secure Boot 导致的模块故障。一、先看懂启动链报错出现在哪一层Ubuntu 从按下电源到进入桌面大致会经历下面几个阶段启动阶段主要工作常见故障表现UEFI/BIOS初始化硬件并寻找启动项找不到启动盘、没有 Ubuntu 启动项GRUB显示内核菜单并传递启动参数GRUB 菜单消失、菜单损坏、选项错误Linux Kernel初始化 CPU、内存和基础设备选择内核后立刻重启、Kernel Panicinitramfs加载早期驱动并找到根文件系统掉进(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 机器开机时可以尝试按住ShiftUEFI 机器通常连续按Esc。不同电脑的固件启动速度不同按键时机可能需要试几次。进入 GRUB 后选择Advanced options for Ubuntu一般可以看到新旧内核及其 recovery mode例如Ubuntu, with Linux6.x.y-new-genericUbuntu, with Linux6.x.y-new-generic (recovery mode)Ubuntu, with Linux6.x.y-old-genericUbuntu, with Linux6.x.y-old-generic (recovery mode)先选择旧内核的普通启动项。只要旧内核还能进入系统后面的检查和修复都会轻松很多。2.2 确认当前真正运行的内核进入系统后先执行uname-r不要只看 GRUB 菜单里选了哪个uname -r才是当前真正运行的版本。查看系统中已经安装的内核包dpkg-llinux-image-*|grep^ii再检查/boot中的新旧内核文件是否都存在ls-lh/boot重点关注vmlinuz-version内核镜像initrd.img-version对应的 initramfsconfig-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 /再检查 inodedf-i/boot /如果更新过程中出现No space left on device不要只看/的剩余空间。单独挂载的/boot可能已经满了。排查到这里时先别急着重建所有东西。先确认磁盘空间、包状态和新内核目录完整否则后面的update-initramfs仍会失败。四、重建新内核的 initramfs 和 GRUB4.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 fs4.2 确认目标内核版本查看模块目录ls/lib/modules假设故障内核是6.x.y-new-generic可以先设置变量NEW_KERNEL6.x.y-new-generic检查目录是否存在test-d/lib/modules/$NEW_KERNELechomodules directory exists再检查内核与 initrdls-lh/boot/vmlinuz-$NEW_KERNEL\/boot/initrd.img-$NEW_KERNEL4.3 更新或重新创建 initramfs更新已有 initramfssudoupdate-initramfs-u-k$NEW_KERNEL如果对应 initrd 根本不存在可以创建sudoupdate-initramfs-c-k$NEW_KERNEL-u是更新-c是创建。不要为了“重来一次”直接手工删除/boot/initrd.img-*否则包管理状态和实际文件更容易对不上。完成后检查ls-lh/boot/initrd.img-$NEW_KERNEL4.4 查看 initramfs 里有没有关键模块lsinitramfs/boot/initrd.img-$NEW_KERNEL|less搜索常见存储、加密和 LVM 组件lsinitramfs/boot/initrd.img-$NEW_KERNEL\|grep-Einvme|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 核对真实 UUIDlsblk-f或者sudoblkid查看系统配置cat/etc/fstab重点核对根分区//boot/boot/efiswap 或resume对应分区额外数据盘。UUID 发生变化的常见原因包括克隆磁盘、恢复快照、重建文件系统、调整 LVM、替换硬盘和手工改分区。尽量不要在 fstab 中长期写死/dev/sdaX、/dev/nvme0n1pX。设备枚举顺序变化后名称可能改变而 UUID 通常更稳定。5.2 检查 GRUB 传递的rootgrep-nlinux.*root/boot/grub/grub.cfg|headgrub.cfg一般由工具生成不建议直接长期手改。应修正/etc/default/grub、/etc/fstab或相关脚本再执行sudoupdate-grub5.3 在 GRUB 中临时修改参数在 GRUB 菜单选中启动项后按e找到以linux开头的一行。常用的临时诊断操作删除quiet splash直接观察详细启动日志加入nomodeset判断是否卡在显卡模式设置检查rootUUID...是否与真实根分区一致检查错误的resume、IOMMU、模块黑名单或显卡参数。临时修改只对本次启动有效不会自动写回配置。nomodeset适合帮助进入系统和判断问题方向但它通常不是显卡问题的最终解决方案。六、DKMS为什么新内核装好了驱动却没跟上6.1 DKMS 模块与内核版本绑定NVIDIA、VirtualBox、ZFS 以及部分网卡驱动使用 DKMS。它们并不是跟着内核镜像天然存在而是要针对每一个内核版本单独构建模块。检查状态dkms status可能看到module/version, old-kernel, installed module/version, new-kernel, addedadded、built和installed不是一回事。要让新内核正常使用该模块目标版本通常需要达到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 并重新构建检查 headersdpkg-llinux-headers-$NEW_KERNEL缺少时安装sudoaptinstalllinux-headers-$NEW_KERNEL重新构建sudodkms autoinstall-k$NEW_KERNEL完成后重建 initramfs 和 GRUBsudoupdate-initramfs-u-k$NEW_KERNELsudoupdate-grub6.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具体操作放在下篇。参考资料Ubuntu Kernelhttps://ubuntu.com/kernelUbuntu GRUB 2https://help.ubuntu.com/community/Grub2update-initramfs手册https://manpages.ubuntu.com/manpages/jammy/en/man8/update-initramfs.8.htmlDKMShttps://github.com/dell/dkmsLinux Kernel initrdhttps://docs.kernel.org/admin-guide/initrd.html