【环境配置】Ubuntu 24.04 升级新内核后 Kernel Panic:NVIDIA DKMS 编译失败导致 initramfs 缺失的修复过程

【故障排查记录】Ubuntu 24.04 升级新内核后 Kernel Panic:NVIDIA DKMS 编译失败导致 initramfs 缺失的修复过程

1. 问题背景

服务器系统为 Ubuntu 24.04,配置了 4 张 NVIDIA GeForce RTX 2080 Ti。

系统升级后安装了新的 Linux 内核:

bash 复制代码
7.0.0-28-generic

但服务器在使用新内核启动时出现异常,最终只能通过 GRUB 选择旧内核:

bash 复制代码
6.17.0-35-generic

进入系统。

最开始怀疑是突然断电或 initramfs 损坏导致 Kernel Panic,因此进入旧内核后开始检查新内核状态。


2. 查看当前系统中的内核

首先查看安装过的内核:

bash 复制代码
dpkg --list | grep linux-image

关键输出如下:

text 复制代码
ii  linux-image-6.17.0-35-generic
iF  linux-image-7.0.0-28-generic
ii  linux-image-generic-hwe-24.04

其中:

text 复制代码
ii

表示软件包已经正常安装并配置完成。

text 复制代码
iF

表示软件包已经安装,但配置失败。

因此可以确定:

text 复制代码
6.17.0-35-generic

是正常可用的旧内核,而:

text 复制代码
7.0.0-28-generic

虽然已经安装,但没有完成配置。

查看当前正在运行的内核:

bash 复制代码
uname -r

输出:

text 复制代码
6.17.0-35-generic

说明当前确实是通过旧内核启动的。


3. 检查 /boot 中的新内核文件

执行:

bash 复制代码
ls -lh /boot | grep -E '6.17.0-35|7.0.0-28'

当时发现:

text 复制代码
vmlinuz-7.0.0-28-generic

已经存在,但是:

text 复制代码
initrd.img-7.0.0-28-generic

并不存在。

虽然有:

text 复制代码
initrd.img -> initrd.img-7.0.0-28-generic

但它只是一个符号链接,实际目标文件并没有生成。

这意味着新内核虽然有 kernel image,但缺少正常启动所需的 initramfs。

检查磁盘空间:

bash 复制代码
df -h /boot /

结果磁盘空间非常充足,因此可以排除 /boot 空间不足的问题。


4. 使用 dpkg 继续配置新内核

执行:

bash 复制代码
sudo dpkg --configure -a

出现关键报错:

text 复制代码
Error! nvidia/570.195.03 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!

随后 NVIDIA 570.211.01 尝试为 7.0.0-28 编译 DKMS 模块:

text 复制代码
Autoinstall of module nvidia/570.211.01 for kernel 7.0.0-28-generic

最终失败:

text 复制代码
Building module(s)...............(bad exit status: 2)

Error! Bad return status for module build on kernel: 7.0.0-28-generic

并进一步导致:

text 复制代码
linux-headers-7.0.0-28-generic
linux-headers-generic-hwe-24.04
linux-generic-hwe-24.04
linux-image-7.0.0-28-generic

全部配置失败。


5. 确认 NVIDIA DKMS 状态

执行:

bash 复制代码
dkms status

发现:

text 复制代码
nvidia/570.195.03: broken
nvidia/570.211.01, 6.17.0-35-generic, x86_64: installed

这说明存在两个不同的问题。

第一个是旧的 NVIDIA DKMS 570.195.03 已经损坏。

第二个是当前 NVIDIA 570.211.01 可以正常工作在:

text 复制代码
6.17.0-35-generic

但无法针对:

text 复制代码
7.0.0-28-generic

完成编译。


6. 清理损坏的 NVIDIA 570.195.03 DKMS 残留

尝试正常删除:

bash 复制代码
sudo dkms remove nvidia/570.195.03 --all

但失败:

text 复制代码
Error! nvidia/570.195.03 is broken!
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!

说明该 DKMS 条目的源码目录已经丢失,DKMS 本身无法正常删除。

因此手动删除损坏的 DKMS 状态目录:

bash 复制代码
sudo rm -rf /var/lib/dkms/nvidia/570.195.03

再次检查:

bash 复制代码
dkms status

此时只剩:

text 复制代码
nvidia/570.211.01, 6.17.0-35-generic, x86_64: installed

旧的 broken 条目已经清理完成。


7. 查看 NVIDIA 570.211.01 的真正编译错误

执行:

bash 复制代码
grep -iE 'error:|fatal:' \
/var/lib/dkms/nvidia/570.211.01/build/make.log | tail -30

出现大量内核 API 相关错误:

text 复制代码
error: 'struct vm_area_struct' has no member named '__vm_flags'
error: implicit declaration of function 'in_irq'
error: 'const struct dma_map_ops' has no member named 'map_resource'
error: 'VMA_LOCK_OFFSET' undeclared
error: too many arguments to function '__is_vma_write_locked'

至此可以确认:

问题并不是 initramfs 命令本身失败,也不是磁盘空间不足,而是:

text 复制代码
NVIDIA 570.211.01

与:

text 复制代码
Linux 7.0.0-28

之间存在内核接口兼容问题。

因此 NVIDIA DKMS 编译失败,进一步导致新内核配置失败,最终导致 initramfs 无法正常生成。

故障链可以概括为:

text 复制代码
NVIDIA 570.211.01 与 Linux 7.0 API 不兼容
                ↓
DKMS 编译失败
                ↓
linux-headers 配置失败
                ↓
linux-image 配置失败
                ↓
initramfs 未生成
                ↓
新内核无法正常启动

8. 确认显卡和 Ubuntu 推荐驱动

查看显卡:

bash 复制代码
nvidia-smi --query-gpu=name,driver_version --format=csv,noheader

输出:

text 复制代码
NVIDIA GeForce RTX 2080 Ti, 570.211.01
NVIDIA GeForce RTX 2080 Ti, 570.211.01
NVIDIA GeForce RTX 2080 Ti, 570.211.01
NVIDIA GeForce RTX 2080 Ti, 570.211.01

服务器共有 4 张 RTX 2080 Ti。

查看 Ubuntu 推荐驱动:

bash 复制代码
ubuntu-drivers devices

其中显示:

text 复制代码
nvidia-driver-595-open - distro non-free recommended

因此决定将 NVIDIA 570 驱动升级为:

text 复制代码
nvidia-driver-595-open

9. 安装 NVIDIA 595-open 时遇到新的包冲突

执行安装:

bash 复制代码
sudo apt update
sudo apt install nvidia-driver-595-open

安装过程中出现:

text 复制代码
dpkg: error processing archive ... libnvidia-gl-595 ...
trying to overwrite
'/usr/lib/x86_64-linux-gnu/libnvidia-egl-xcb.so.1.0.5',
which is also in package libnvidia-egl-xcb1:amd64 1.0.5-1ubuntu1

说明系统中已有:

text 复制代码
libnvidia-egl-xcb1

而新的:

text 复制代码
libnvidia-gl-595

也要安装同一个文件,因此发生 dpkg 文件冲突。

查看相关包:

bash 复制代码
dpkg -l | grep -E 'libnvidia-egl-(xcb|xlib|gbm)'

发现:

text 复制代码
ii  libnvidia-egl-xcb1:amd64
ii  libnvidia-egl-xlib1:amd64

10. 清理冲突的 EGL 包

直接使用 apt 删除时:

bash 复制代码
sudo apt remove libnvidia-egl-xcb1 libnvidia-egl-xlib1

由于系统此时已经处于依赖未完成状态,apt 无法完成删除。

因此改用 dpkg 删除:

bash 复制代码
sudo dpkg -r libnvidia-egl-xcb1:amd64 libnvidia-egl-xlib1:amd64

如果因为依赖关系仍然无法删除,可以执行:

bash 复制代码
sudo dpkg --remove --force-depends \
  libnvidia-egl-xcb1:amd64 \
  libnvidia-egl-xlib1:amd64

这里的目的只是临时解除冲突,后续立即让 apt 修复依赖关系。

然后执行:

bash 复制代码
sudo apt --fix-broken install

使系统继续完成:

text 复制代码
libnvidia-gl-595
nvidia-kernel-source-595-open
nvidia-dkms-595-open
nvidia-utils-595
nvidia-driver-595-open

等相关软件包的安装和配置。


11. 完成所有软件包配置

执行:

bash 复制代码
sudo dpkg --configure -a

这一次没有再出现错误。

检查 DKMS:

bash 复制代码
dkms status

最终输出:

text 复制代码
nvidia/595.84, 6.17.0-35-generic, x86_64: installed
nvidia/595.84, 7.0.0-28-generic, x86_64: installed

这说明 NVIDIA 595.84 已经成功同时为两个内核生成模块:

text 复制代码
6.17.0-35-generic
7.0.0-28-generic

检查 dpkg 状态:

bash 复制代码
dpkg --audit

无任何输出,说明系统中已经没有处于未完成配置状态的软件包。


12. 重新生成 7.0.0-28 的 initramfs

检查:

bash 复制代码
ls -lh /boot/initrd.img-7.0.0-28-generic

已经看到:

text 复制代码
-rw-r--r-- 1 root root 76M ... /boot/initrd.img-7.0.0-28-generic

为了确保 initramfs 内容完整,再执行:

bash 复制代码
sudo update-initramfs -u -k 7.0.0-28-generic

输出:

text 复制代码
update-initramfs: Generating /boot/initrd.img-7.0.0-28-generic

期间出现:

text 复制代码
I: The initramfs will attempt to resume from /dev/nvme0n1p1

这只是休眠恢复设备提示,不属于错误。


13. 更新 GRUB

执行:

bash 复制代码
sudo update-grub

成功识别两个内核:

text 复制代码
Found linux image: /boot/vmlinuz-7.0.0-28-generic
Found initrd image: /boot/initrd.img-7.0.0-28-generic

Found linux image: /boot/vmlinuz-6.17.0-35-generic
Found initrd image: /boot/initrd.img-6.17.0-35-generic

此时 /boot 中的新旧内核均完整:

text 复制代码
vmlinuz-6.17.0-35-generic
initrd.img-6.17.0-35-generic

vmlinuz-7.0.0-28-generic
initrd.img-7.0.0-28-generic

14. 保留旧内核作为救援内核

在整个修复过程中,没有删除:

text 复制代码
6.17.0-35-generic

并将其标记为手动安装:

bash 复制代码
sudo apt-mark manual \
  linux-image-6.17.0-35-generic \
  linux-modules-6.17.0-35-generic

这样可以降低它被:

bash 复制代码
apt autoremove

误清理的风险。

对于服务器而言,保留一个已经验证能够正常启动的旧内核非常有必要。


15. 重启验证

确认所有步骤完成后执行:

bash 复制代码
sudo reboot

服务器重新启动后:

bash 复制代码
uname -r

输出:

text 复制代码
7.0.0-28-generic

说明新内核已经正常启动。


16. 验证 NVIDIA 驱动

执行:

bash 复制代码
nvidia-smi

结果:

text 复制代码
NVIDIA-SMI 595.84
Driver Version: 595.84
CUDA Version: 13.2

4 张 RTX 2080 Ti 全部正常识别:

text 复制代码
GPU 0  NVIDIA GeForce RTX 2080 Ti
GPU 1  NVIDIA GeForce RTX 2080 Ti
GPU 2  NVIDIA GeForce RTX 2080 Ti
GPU 3  NVIDIA GeForce RTX 2080 Ti

说明 NVIDIA 驱动已经恢复正常。


17. 再次验证 DKMS

执行:

bash 复制代码
dkms status

输出:

text 复制代码
nvidia/595.84, 6.17.0-35-generic, x86_64: installed
nvidia/595.84, 7.0.0-28-generic, x86_64: installed

说明两个内核都已经具备对应的 NVIDIA 内核模块。


18. 检查系统服务

执行:

bash 复制代码
systemctl --failed

输出:

text 复制代码
0 loaded units listed.

说明系统启动后没有失败的 systemd 服务。

至此故障彻底解决。


19. 最终解决方案总结

这次问题最初表现为:

text 复制代码
Ubuntu 新内核启动失败 / Kernel Panic

但真正原因并不是单纯的 initramfs 损坏,而是:

text 复制代码
Linux 7.0.0-28
        +
NVIDIA 570.211.01
        ↓
DKMS 编译失败

最终导致:

text 复制代码
DKMS failure
    ↓
linux-headers 配置失败
    ↓
linux-image 配置失败
    ↓
initramfs 缺失
    ↓
新内核无法启动

实际修复过程为:

text 复制代码
1. 使用旧内核 6.17.0-35 启动系统
              ↓
2. 保留旧内核,不进行 autoremove
              ↓
3. 清理损坏的 nvidia/570.195.03 DKMS 残留
              ↓
4. 确认 570.211.01 无法适配 Linux 7.0
              ↓
5. 升级到 nvidia-driver-595-open
              ↓
6. 处理 libnvidia-egl-xcb1 / xlib1 文件冲突
              ↓
7. apt --fix-broken install
              ↓
8. dpkg --configure -a
              ↓
9. NVIDIA 595.84 成功为两个内核构建 DKMS
              ↓
10. 重新生成 initramfs
              ↓
11. update-grub
              ↓
12. 重启进入 7.0.0-28
              ↓
13. nvidia-smi / DKMS / systemd 全部正常

20. 本次最终状态

当前内核:

bash 复制代码
uname -r
text 复制代码
7.0.0-28-generic

NVIDIA 驱动:

text 复制代码
595.84

CUDA Driver API 显示版本:

text 复制代码
CUDA Version: 13.2

GPU:

text 复制代码
4 × NVIDIA GeForce RTX 2080 Ti

DKMS:

text 复制代码
nvidia/595.84, 6.17.0-35-generic, x86_64: installed
nvidia/595.84, 7.0.0-28-generic, x86_64: installed

系统失败服务:

text 复制代码
0 loaded units listed.

系统已经恢复正常。


21. 一些经验总结

21.1 不要看到 Kernel Panic 就直接认定是 initramfs 损坏

initramfs 缺失有时只是结果。

本次真正的上游原因是:

text 复制代码
NVIDIA DKMS 无法针对新内核编译

因此应当优先查看:

bash 复制代码
sudo dpkg --configure -a

以及:

bash 复制代码
dkms status

和:

bash 复制代码
/var/lib/dkms/<模块>/<版本>/build/make.log

21.2 新内核启动失败时不要急着删除旧内核

旧内核:

text 复制代码
6.17.0-35-generic

是本次整个修复过程能够顺利完成的关键。

服务器上建议至少保留一个已经验证可正常启动的旧内核。

可以使用:

bash 复制代码
sudo apt-mark manual \
  linux-image-6.17.0-35-generic \
  linux-modules-6.17.0-35-generic

防止其被自动清理。


21.3 DKMS 报错时一定要看 make.log

只看到:

text 复制代码
Bad return status for module build

无法确定真正原因。

应该继续查看:

bash 复制代码
grep -iE 'error:|fatal:' \
/var/lib/dkms/nvidia/<版本>/build/make.log | tail -30

本次就是通过日志中的:

text 复制代码
__vm_flags
VMA_LOCK_OFFSET
map_resource
in_irq

最终确认 NVIDIA 570 与新内核 API 不兼容。


21.4 不建议直接使用 rm 删除系统动态库

遇到:

text 复制代码
trying to overwrite ...

不要直接删除:

text 复制代码
/usr/lib/x86_64-linux-gnu/

下的文件。

应该先使用:

bash 复制代码
dpkg -S 文件路径

确认该文件属于哪个包,然后从包管理层面处理。


21.5 不要在系统包状态异常时执行 apt autoremove

如果:

bash 复制代码
dpkg --audit

仍然有异常,或者:

bash 复制代码
dkms status

仍有 broken 状态,不建议执行:

bash 复制代码
sudo apt autoremove

否则有可能把仍然需要的旧内核、驱动或依赖一起清理掉。


22. 常用排查命令汇总

查看当前内核:

bash 复制代码
uname -r

查看已安装内核:

bash 复制代码
dpkg --list | grep '^ii' | grep 'linux-image-[0-9]'

查看 /boot

bash 复制代码
ls -lh /boot

查看 DKMS:

bash 复制代码
dkms status

检查 dpkg:

bash 复制代码
sudo dpkg --audit

继续配置未完成的软件包:

bash 复制代码
sudo dpkg --configure -a

修复依赖:

bash 复制代码
sudo apt --fix-broken install

查看 NVIDIA:

bash 复制代码
nvidia-smi

查看推荐驱动:

bash 复制代码
ubuntu-drivers devices

重新生成指定内核 initramfs:

bash 复制代码
sudo update-initramfs -u -k <kernel-version>

更新 GRUB:

bash 复制代码
sudo update-grub

查看系统启动失败服务:

bash 复制代码
systemctl --failed

结语

这次故障表面上是 Ubuntu 新内核启动失败和 initramfs 缺失,实际上是一条典型的"驱动兼容性问题引发内核包配置失败"的故障链。

最终解决问题的关键不是单纯反复执行:

bash 复制代码
update-initramfs

而是先处理:

text 复制代码
NVIDIA DKMS 与新 Linux 内核之间的兼容问题

只有 DKMS 能够成功编译,新内核软件包才能完成配置,initramfs 才能正常生成,GRUB 才能最终启动新内核。

相关推荐
富唯智能机器人3 小时前
CNC 精密加工复合机器人上下料解决方案|柔性车间自动化|富唯智能
经验分享
我要 调查网4 小时前
目标客户群体市场调查的分析维度
经验分享
yuenineon5 小时前
应付对账总卡壳?财务机器人在采购到付款环节能做什么
经验分享
畅想视界ThinkView6 小时前
中医理疗机构智能终端选型指南:场景拆解与参数避坑(附对照表)
经验分享·电脑
Ztt6666666667 小时前
竹节密封罐披上紫釉,硬朗筋骨也有柔和一面
经验分享·笔记·其他·百度·微信公众平台
FLJwu8 小时前
传感器与图像 ISP 实战 03:运动相机图像量产一致性|批次色差、白平衡漂移、整机标定与出厂图像质检方案|20 年源头工厂量产经验
图像处理·经验分享·数码相机·相机·isp
louiseailife8 小时前
如何评估一项任务是否适合自动化改造
经验分享
IT小白杨9 小时前
跨境电商账号关联归因链路拆解与可落地环境配置
服务器·网络·经验分享·安全·指纹浏览器
m0_7196408710 小时前
高校科研如何选型适配具身智能研究的VR遥操机器人
经验分享