每次内核更新后都要重新安装网卡驱动?这种反复折腾的日子该结束了。本文将带你深入理解DKMS机制,并提供一套完整的解决方案,让你的Realtek网卡驱动在内核更新后依然坚挺如初。
当你在Ubuntu 18.04上手动编译安装Realtek网卡驱动时,通常使用的是make install方式。这种方式会将编译好的内核模块(.ko文件)直接安装到当前运行内核的模块目录中,比如/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/。
然而,Linux内核的一个特点是:每个内核版本都有自己独立的模块目录。当系统通过apt upgrade更新内核时,会安装一个全新的内核版本,并保留旧内核作为备用。这时会发生以下情况:
这就是为什么每次内核更新后都需要重新安装驱动的原因。要解决这个问题,我们需要一个能自动为每个新内核编译和安装驱动的机制——这就是DKMS的用武之地。
DKMS(Dynamic Kernel Module Support)是Linux内核的一个框架,专门用于管理第三方内核模块的生命周期。它的核心优势在于:
DKMS的工作流程大致如下:
/usr/src/<module>-<version>/dkms add注册模块dkms build和dkms install为当前内核构建安装模块bash复制# DKMS模块目录结构示例
/usr/src/r8125-9.009.01/
├── dkms.conf
├── src
│ ├── Makefile
│ └── r8125.c
└── net_recovery.sh
首先确保你已经从Realtek官网下载了正确的驱动源码包。对于RTL8125网卡,通常文件名类似r8125-9.009.01.tar.bz2。
bash复制# 解压驱动包
tar -xjvf r8125-9.009.01.tar.bz2
cd r8125-9.009.01
# 将源码复制到DKMS目录
sudo cp -r ~/r8125-9.009.01 /usr/src/
在驱动源码目录中创建dkms.conf文件,这是DKMS的核心配置文件:
bash复制cd /usr/src/r8125-9.009.01
sudo nano dkms.conf
文件内容示例(根据实际情况修改版本号):
code复制PACKAGE_NAME="Realtek_r8125"
PACKAGE_VERSION="9.009.01"
DEST_MODULE_LOCATION="/updates/dkms"
BUILT_MODULE_NAME="r8125"
BUILT_MODULE_LOCATION="src/"
MAKE[0]="'make' -C src/ all"
CLEAN="'make' -C src/ clean"
AUTOINSTALL="yes"
关键参数说明:
| 参数 | 说明 |
|---|---|
PACKAGE_NAME |
DKMS模块的名称 |
PACKAGE_VERSION |
驱动版本号,必须与目录名一致 |
DEST_MODULE_LOCATION |
模块安装的相对路径 |
BUILT_MODULE_NAME |
生成的模块文件名(不含.ko) |
AUTOINSTALL |
是否在新内核上自动安装 |
执行以下命令将模块添加到DKMS系统并构建:
bash复制# 添加模块到DKMS
sudo dkms add -m r8125 -v 9.009.01
# 构建模块
sudo dkms build -m r8125 -v 9.009.01
# 安装模块
sudo dkms install -m r8125 -v 9.009.01
# 加载模块
sudo modprobe r8125
验证模块是否安装成功:
bash复制dkms status
# 应该看到类似输出:
# r8125, 9.009.01, 5.4.0-135-generic, x86_64: installed
虽然DKMS能自动处理大多数情况,但有时仍可能需要手动干预。创建一个自动恢复脚本是个好主意:
bash复制#!/bin/bash
# /usr/src/r8125-9.009.01/net_recovery.sh
# 重新安装DKMS模块
dkms install -m r8125 -v 9.009.01 --force
# 更新模块依赖关系
depmod -a
# 重新加载模块
modprobe -r r8125
modprobe r8125
echo "网卡驱动已恢复"
给脚本执行权限并创建快捷方式:
bash复制chmod +x /usr/src/r8125-9.009.01/net_recovery.sh
ln -s /usr/src/r8125-9.009.01/net_recovery.sh ~/net_recovery
以后遇到驱动问题时,只需运行:
bash复制sudo ~/net_recovery
如果你希望更彻底地避免驱动问题,可以考虑以下内核管理策略:
方案一:临时禁止内核自动更新
bash复制# 锁定当前内核版本
sudo apt-mark hold linux-image-$(uname -r)
sudo apt-mark hold linux-headers-$(uname -r)
# 解除锁定(需要更新时)
sudo apt-mark unhold linux-image-$(uname -r)
sudo apt-mark unhold linux-headers-$(uname -r)
方案二:选择性更新
bash复制# 排除特定包更新
sudo apt-get update
sudo apt-get upgrade -y -o Dpkg::Options::="--force-confold" --exclude=linux-image-*,linux-headers-*
注意:长期不更新内核可能存在安全隐患,建议仅在关键时期使用锁定功能,平时保持DKMS正常工作即可。
即使配置了DKMS,偶尔也会遇到问题。以下是一些常见情况及解决方法:
问题1:内核更新后驱动未自动安装
检查DKMS服务状态:
bash复制systemctl status dkms
如果服务未运行,可以手动触发:
bash复制sudo dkms autoinstall
问题2:模块编译失败
查看详细编译日志:
bash复制cat /var/lib/dkms/r8125/9.009.01/build/make.log
常见原因及解决:
内核头文件缺失:安装对应版本的头文件
bash复制sudo apt install linux-headers-$(uname -r)
编译器版本不兼容:安装较旧版本的gcc
bash复制sudo apt install gcc-8
sudo update-alternatives --config gcc
问题3:模块加载失败
检查内核日志:
bash复制dmesg | grep r8125
常见错误:
为了确保你的Realtek网卡驱动长期稳定工作,建议遵循以下实践:
定期检查DKMS状态
bash复制dkms status
保持驱动更新
建立系统监控
文档记录
bash复制# 示例监控脚本
#!/bin/bash
if ! ip link show eth0 | grep -q "state UP"; then
/usr/src/r8125-9.009.01/net_recovery.sh
echo "$(date): 网卡异常,已尝试恢复" >> /var/log/network_monitor.log
fi
将这些技巧结合起来,你的Ubuntu 18.04系统将拥有一个真正"一劳永逸"的Realtek网卡驱动解决方案,再也不用担心内核更新带来的网络中断问题。