在长期使用 Arch Linux 的过程中,内核会不断更新,系统也会留下许多历史内核版本的残留模块目录。这些残留文件虽然通常不会影响正常启动,但在安装或编译 DKMS(动态内核模块,如无线网卡驱动、显卡驱动等)时,常常会提示「为旧内核编译失败」的错误,影响体验。
这篇文章记录一次系统性清理旧内核文件的全过程,并分析 DKMS 触发机制,最终彻底解决编译提示问题。
💡 背景
Arch Linux 采用滚动更新模式,经常自动升级到最新内核。每次升级时,pacman 会安装新内核并更新 /usr/lib/modules 目录。然而,老版本内核的模块目录并不会自动删除,导致大量「历史残留」。
例如,/usr/lib/modules 中可能出现如下目录:
5.15.29-1-lts
5.15.30-1-lts
5.16.16-arch1-1
6.7.6-zen1-1-zen
6.14.10-arch1-1
6.15.2-arch1-1 ← 当前使用内核
⚠️ 问题表现
在安装 DKMS 驱动(如 snd-hda-macbookpro、rtl88x2bu 等)时,经常出现以下提示:
为内核 5.16.16-arch1-1 编译失败:找不到内核头文件或符号表
虽然不影响当前系统的正常运行,但会导致日志或安装输出杂乱,给人一种「系统不干净」的印象。
🔎 原因分析
DKMS 如何决定编译哪些内核
DKMS 并不是对 /usr/lib/modules 中每个目录都强制编译,而是根据以下条件判断:
- 目录内存在
build符号链接(指向对应内核头文件) - 目录中存在有效的内核符号文件(如
Module.symvers、modules.dep等)
只要 build 文件存在,即使该内核实际已被卸载,DKMS 仍然会尝试为其编译驱动,最终导致提示错误。
✅ 彻底解决思路
1️⃣ 清理 /usr/lib/modules 旧内核目录
首先,确认当前正在使用的内核版本,例如:
uname -r
输出示例:
6.15.2-arch1-1
在 /usr/lib/modules 中,仅保留对应的目录即可,其余目录全部清空或删除。
2️⃣ 保留空壳目录(可选)
若希望保留历史目录作为「系统成长记录」,可以只清空目录内文件,保留空壳目录名称,既纪念又节省空间。
示例清空命令(保留空壳):
for dir in /usr/lib/modules/*; do
if [[ "$(basename "$dir")" != "6.15.2-arch1-1" ]]; then
sudo rm -rf "$dir"/*
fi
done
3️⃣ 清理 /boot
确认 /boot 目录中是否残留旧内核文件(如 vmlinuz-xxx, initramfs-xxx.img),一般只需要以下文件:
vmlinuz-linuxinitramfs-linux.imginitramfs-linux-fallback.imgintel-ucode.img(或amd-ucode.img)
如有旧文件,可手动删除。
4️⃣ 检查已安装内核包
pacman -Q | grep '^linux'
输出中应仅有一个当前内核版本及其头文件(linux-headers)。若有其他历史版本,可卸载。
5️⃣ 清理 pacman 缓存(可选)
sudo paccache -r -k1
只保留最新版本包,进一步节省空间。
✅ 清理后效果
- 所有旧内核目录已清空,只剩空壳(约 4K)
- DKMS 编译时只针对当前内核,不再提示错误
/boot及/usr/lib/modules状态干净整洁- 系统更轻盈,驱动编译更快、更稳定
💬 总结
- 内核长期更新过程中,系统容易遗留多个
/usr/lib/modules/旧版本目录 - 这些目录内的
build符号链接会导致 DKMS 反复尝试编译旧内核 - 清空目录内容、删除不必要文件、保留空壳或直接删除目录,是彻底解决方法
- 清理完成后,未来在安装任何 DKMS 驱动(无线网卡、显卡、声卡等)时,均不会再出现「为旧内核编译失败」提示
🌟 附加
若希望保留更详细记录,可将各个内核目录及占用空间生成 Markdown 清单,或者将操作日志保存作为系统成长档案,记录从系统最初安装(如 2021 年 11 月)到现在的内核演变历史。
🟢 参考命令
查看 /usr/lib/modules 所有目录大小:
du -sh /usr/lib/modules/*
✅ 结束
通过本次系统性清理,Arch Linux 环境更加干净,未来编译 DKMS 驱动将更高效稳定。系统也可持续保持轻量、可控的状态,为后续长期使用打下更坚实的基础。