Ubuntu 开机 Kernel Panic:HWE 内核升级失败 + NVIDIA DKMS 踩坑实录

Ubuntu 开机 Kernel Panic:HWE 内核升级失败 + NVIDIA DKMS 踩坑实录

环境:Ubuntu 24.04.2 LTS(Noble)· NVIDIA GeForce RTX 4090 · 驱动 570.211.01(DKMS)

时间:2026-07

关键词:kernel panicunattended-upgradeHWEinitrdnvidia-dkms


写在前面

这台工作站某天突然开机即崩。从 Advanced Options 选了一个旧内核(非 recovery)后,SSH 还能连上,于是把问题从头到尾查清楚并修掉了。

这篇记录的是:现象 → 证据 → 根因 → 修复 → 经验。如果你也在 Ubuntu 上开着无人值守升级,并且装了 NVIDIA 闭源驱动,很可能迟早会碰到同类坑。


一、现象

  • 正常开机:直接 kernel panic / 起不来
  • GRUB → Advanced options → 选旧内核(没有勾 recovery):可以进系统,网络和 SSH 正常
  • 机器用途允许重启,但修复前需要先摸清原因

表面看像"内核坏了",实际更常见的是:默认引导项指向了一个半残的新内核


二、诊断思路(只读排查)

按这个顺序查,通常很快能定位:

  1. 当前到底跑的哪个内核、/boot 里有什么
  2. 上一次/最近的 apt / unattended-upgrade 有没有失败
  3. 新内核是否缺 initrd、包是不是 half-configured
  4. 有没有 NVIDIA DKMS / crash 报告

2.1 关键发现

当时系统实际运行的是可用旧核:

text 复制代码
6.17.0-40-generic

/boot 里已经出现了新内核 7.0.0-28-generic,同时:

检查项 结果
/boot/vmlinuz 指向 vmlinuz-7.0.0-28-generic
/boot/initrd.img 指向 initrd.img-7.0.0-28-generic
initrd.img-7.0.0-28-generic 文件本身 不存在
linux-image-7.0.0-28-generic install ok half-configured
GRUB GRUB_DEFAULT=0TIMEOUT=0(默认静默进第一项)

也就是说:默认启动 7.0,但 7.0 的 initrd 根本没生成。 这足以导致开机阶段直接失败;很多用户会把它笼统叫成 "kernel panic"。

2.2 是谁装上的 7.0?

/var/log/apt/history.log 里写得很清楚:

text 复制代码
Start-Date: 2026-07-21  08:28:49
Commandline: /usr/bin/unattended-upgrade
Install: ... linux-image-7.0.0-28-generic ...
Upgrade: linux-generic-hwe-24.04 ... 6.17.0-40 → 7.0.0-28
Error: Sub-process /usr/bin/dpkg returned an error code (1)

不是人手敲的 apt upgrade,而是 systemd 定时触发的无人值守升级

对应配置大致是:

  • /etc/apt/apt.conf.d/20auto-upgradesAPT::Periodic::Unattended-Upgrade "1"
  • apt-daily-upgrade.timer 每天自动跑
  • 50unattended-upgrades 里允许 noble / noble-security
  • 黑名单里本可排除 linux-,但那一行默认是注释掉的 ,所以 HWE 内核元包会被自动升级

2.3 为什么安装会失败?

/var/crash/ 里有一份可读的 NVIDIA DKMS 崩溃报告,核心是:

nvidia-dkms-570(570.211.01)在内核 7.0.0-28-generic 上编译失败

典型报错涉及内核 API 变化(例如 dma_map_ops / map_resource 相关)

连锁反应是:

  1. HWE 元包把系统带到 7.0
  2. 安装/配置阶段触发 DKMS 给新核编 NVIDIA 模块 → 失败
  3. linux-image / headers 停在 half-configured
  4. initrd 没有正确生成 ,但 /boot 符号链接和 GRUB 默认项已经指向 7.0
  5. 下次开机默认进 7.0 → 崩
  6. 选旧的 6.17.0-40 → 正常(旧核上 NVIDIA 模块本来就是好的)

一句话根因:

无人值守升级把 HWE 升到了与当前 NVIDIA 570 DKMS 不兼容的 7.0 内核,安装半残且缺 initrd,又成了默认引导项。


三、修复方案(本次采用的方案 A)

原则很简单:

  1. 先让机器稳定回到已知可用内核
  2. 清掉半残的 7.0
  3. 关掉会再次自动挖坑的无人值守升级
  4. 把当前可用内核 hold 住,并屏蔽 7.0

注意:下列操作需要 root。生产机操作前先确认有旧内核可回退,并征得重启许可。

3.1 关闭无人值守安全更新

写入 /etc/apt/apt.conf.d/20auto-upgrades

text 复制代码
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::Unattended-Upgrade "0";

并禁用相关定时器/服务:

bash 复制代码
systemctl disable --now apt-daily-upgrade.timer
systemctl disable --now apt-daily.timer
systemctl mask apt-daily-upgrade.service
systemctl mask apt-daily.service
systemctl disable --now unattended-upgrades.service

3.2 用 apt pin 挡住 7.0(可选但推荐)

创建 /etc/apt/preferences.d/block-linux-hwe-7.0.pref

必须带 .pref 后缀,否则 apt 会直接忽略):

text 复制代码
Package: linux-generic-hwe-24.04 linux-image-generic-hwe-24.04 linux-headers-generic-hwe-24.04
Pin: version 7.0.*
Pin-Priority: -1

Package: linux-image-7.0.0-* linux-headers-7.0.0-* linux-modules-7.0.0-* linux-modules-extra-7.0.0-* linux-tools-7.0.0-* linux-hwe-7.0-*
Pin: version *
Pin-Priority: -1

3.3 清除半残 7.0 及相关元包

bash 复制代码
export DEBIAN_FRONTEND=noninteractive

apt-get -y purge \
  linux-generic-hwe-24.04 \
  linux-headers-generic-hwe-24.04 \
  linux-image-generic-hwe-24.04 \
  linux-tools-7.0.0-28-generic \
  linux-headers-7.0.0-28-generic \
  linux-image-7.0.0-28-generic \
  linux-modules-7.0.0-28-generic \
  linux-hwe-7.0-tools-7.0.0-28 \
  linux-hwe-7.0-headers-7.0.0-28

若仍有包卡在 half-configured,可再对单个包强制清理(谨慎使用):

bash 复制代码
dpkg --remove --force-remove-reinstreq --force-depends <包名>
dpkg --purge  --force-remove-reinstreq --force-depends <包名>

清理残留文件(如仍存在):

bash 复制代码
rm -f /boot/vmlinuz-7.0.0-28-generic \
      /boot/initrd.img-7.0.0-28-generic \
      /boot/System.map-7.0.0-28-generic \
      /boot/config-7.0.0-28-generic
rm -rf /lib/modules/7.0.0-28-generic

3.4 恢复可用内核引导

确认 linux-image-6.17.0-40-generic 仍在,然后:

bash 复制代码
update-initramfs -c -k 6.17.0-40-generic
# 或
update-initramfs -u -k 6.17.0-40-generic

ln -sfn vmlinuz-6.17.0-40-generic /boot/vmlinuz
ln -sfn initrd.img-6.17.0-40-generic /boot/initrd.img

适当放开 GRUB 菜单,方便以后再翻车时手动选内核:

bash 复制代码
# /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=3

update-grub

3.5 hold 当前可用内核

bash 复制代码
apt-mark hold \
  linux-image-6.17.0-40-generic \
  linux-modules-6.17.0-40-generic \
  linux-modules-extra-6.17.0-40-generic \
  linux-headers-6.17.0-40-generic \
  linux-hwe-6.17-headers-6.17.0-40 \
  linux-hwe-6.17-tools-6.17.0-40 \
  linux-tools-6.17.0-40-generic

3.6 重启验证

重启后确认:

bash 复制代码
uname -r
# 期望:6.17.0-40-generic

ls -l /boot/vmlinuz /boot/initrd.img
nvidia-smi
systemctl is-enabled apt-daily-upgrade.timer   # disabled
apt-mark showhold | grep linux

本次修复后,机器已用 6.17.0-40-generic 正常启动,nvidia-smi 正常,无人值守升级保持关闭。


四、Recovery 还是旧内核?

这类"新内核装坏了导致默认开机失败"的问题:

入口 建议
Advanced → 旧内核(不要 recovery) 首选。多用户、可联网、可 SSH、方便跑 apt
recovery mode 兜底。适合根分区只读、需要 fsck、连旧核正常模式都进不去时
Live USB 上面都不行再上

经验法则:先找一个"已知能干活"的旧内核正常启动,再修包;不要一上来就 recovery。


五、一点历史:其实坑埋得更早

回看这台机器 2026 年初的日志,会发现同类问题早就出现过:

  • 2026-02-11 :无人值守把 HWE 从 6.14 拉到 6.17.0-14,dpkg 失败
  • 2~3 月linux-image 长期 half-configured,自动任务天天重试失败
  • 3 月中旬:NVIDIA 570 小版本升级也碰过 DKMS 问题
  • 当时更多是靠旧内核继续开机,后来某次自动重试碰巧把包状态配平,并没有像这次这样系统性关掉自动升级

所以这次不是"突然第一次坏",而是:

同一个模式(自动升 HWE + NVIDIA DKMS)反复发作;这次刚好撞上 7.0,且缺 initrd,破坏力更大。


六、可复用的排查命令速查

bash 复制代码
# 当前内核与启动参数
uname -a
cat /proc/cmdline

# /boot 是否缺 initrd、符号链接是否悬空
ls -l /boot/vmlinuz* /boot/initrd.img*

# 包是否半残
dpkg -l 'linux-image-*' | awk '/^i[^i]/ || /half/'
dpkg --audit

# 最近是谁升级的内核
less /var/log/apt/history.log
less /var/log/unattended-upgrades/unattended-upgrades.log

# DKMS / NVIDIA
dkms status
ls /var/crash/

七、经验总结

  1. Ubuntu Desktop/工作站若装了 NVIDIA DKMS,慎开"自动安装安全更新到内核"。 安全源也会推 HWE 内核元包。
  2. 内核升级失败最危险的状态不是"没装上",而是"装了一半还成了默认项"。 尤其要盯 /boot/initrd.img-* 是否真实存在。
  3. 开机崩了,优先选旧内核正常模式,而不是 recovery。
  4. 修完要做三件事:清半残包、修 GRUB/符号链接、阻止再次自动升到不兼容内核。 只"能开机"不够。
  5. preferences.d 里的 pin 文件必须用 .pref 后缀,否则 apt 会忽略。

八、后续可选方向(未在本次执行)

如果你之后仍想跟进 HWE 新内核,更稳妥的路径通常是:

  1. 先确认 NVIDIA 驱动版本已明确支持目标内核
  2. 再手动升级内核,观察 DKMS 与 initrd
  3. 成功后再考虑是否重新打开有限的自动更新(并建议把 linux- 加入 unattended 黑名单)

本次选择是:先稳定在 6.17.0-40,关掉自动升级,把记录留下。 对工作站来说,这往往比"永远最新内核"更重要。


附录:问题因果链(简图)

text 复制代码
apt-daily-upgrade.timer
        │
        ▼
unattended-upgrade
        │
        ▼
linux-*-hwe-24.04  6.17 → 7.0
        │
        ▼
nvidia-dkms-570 编译失败(API 不兼容)
        │
        ▼
linux-image-7.0 half-configured
initrd 未生成,但默认引导已指向 7.0
        │
        ▼
默认开机失败 / kernel panic
        │
        ▼
Advanced 选 6.17.0-40(非 recovery)→ 可修复

记录完毕。若你也遇到"自动更新后开机即崩",先别急着重装:Advanced 里找旧内核,查 /boot 的 initrd 和 dpkg 半残状态,十有八九能救回来。

相关推荐
易筋紫容1 小时前
为什么做了 DevOps,你还是管不好开源依赖?
运维·开源·devops
coder!mq1 小时前
什么是泛型?有什么好处?
linux·运维·服务器·面试题·八股文
日取其半万世不竭10 小时前
用 Portainer 可视化管理 Docker:容器再多也不用背命令了
运维·docker·容器
2023自学中10 小时前
Linux 图形系统
linux
mounter62513 小时前
高性能网络技术演进与创新探索:RDMA、eBPF/XDP 深度解析及 LSF/MM/BPF 2023 专题演讲
linux·ebpf·linux kernel·kernel·rdma·xdp
动恰客流统计13 小时前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
名字还没想好☜13 小时前
Python itertools 实战:用 groupby、chain、islice 优雅处理大数据流
linux·windows·python·迭代器·itertools
啊啊啊迈 旋棍15 小时前
【译】TypeScript 7 测试版已在 Visual Studio 2026 18.6 Insiders 3 中默认启用
ubuntu·typescript·visual studio
ziguo112216 小时前
深入浅出 C/C++ 数据类型:从入门到踩坑
linux·c语言·c++·windows·visual studio