ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu 20.04下RTL8111/8168网卡驱动r8168编译与DKMS配置指南

Ubuntu 20.04下RTL8111/8168网卡驱动r8168编译与DKMS配置指南 1. 为什么RTL8111/8168这块网卡总在Ubuntu上翻车RTL8111/8168系列网卡大概是x86桌面平台和入门级服务器上最常见的有线网卡方案之一从十多年前的B75主板到现在的很多ITX小板、迷你主机、工控机板载网口基本都是这颗芯片的变种。Realtek官方给Linux的驱动包叫r8168而Ubuntu内核里默认带的是r8169开源驱动。问题就出在这里r8169对老版本芯片兼容性还行但遇到RTL8111H、RTL8168H、RTL8111K这些较新的步进版本经常出现网口能识别但跑不满千兆、频繁断流、休眠唤醒后网卡消失、dmesg里刷link up/down日志这类毛病。我手上这台工控机就是典型例子板载RTL8111H装完Ubuntu 20.04之后lspci能看到网卡ip a也能看到enp3s0但插上网线后指示灯闪两下就灭ethtool显示Link detected: no。换网线、换交换机口、换对端设备都试过最后定位到就是r8169驱动和这颗芯片的匹配问题。解决办法不复杂就是换成Realtek官方的r8168驱动但坑在于Ubuntu 20.04默认内核5.4官方驱动源码需要打补丁才能编译通过而且编译完之后如果不做自动加载配置内核更新一次驱动就白装了。这篇内容就是把这套流程从头到尾捋一遍包括驱动源码获取、编译环境准备、DKMS自动重编译、黑名单屏蔽r8169、模块自动加载配置以及实测中遇到的各种报错怎么排查。适合手里有RTL8111/8168系列网卡、在Ubuntu 20.04或同代Debian系发行版上遇到网络问题的朋友参考。整个过程不需要联网下载驱动因为网卡本身就不通所以我会把离线操作的思路也讲清楚。2. 动手之前先把方案想明白2.1 为什么不用内核自带的r8169很多人第一反应是内核都自带驱动了为什么还要折腾这里需要把两个驱动的关系说清楚。r8169是内核社区维护的开源驱动代码在主线内核里优点是开箱即用、随内核更新缺点是它对Realtek全系芯片做通用适配遇到某些步进版本的芯片时硬件初始化时序、PHY配置、电源管理策略可能和芯片实际需求对不上。r8168是Realtek官方提供的闭源驱动针对自家芯片做了针对性优化在链路稳定性、千兆吞吐、节能以太网EEE兼容性上通常表现更好。判断该不该换可以看几个信号dmesg | grep r8169里有没有PHY read fail、link down反复出现ethtool eth0里Speed是不是只有100Mbps而交换机是千兆机器休眠唤醒后网卡是不是直接消失。如果中了任意一条换r8168基本能解决。如果网卡一直跑得好好的那就别动内核自带驱动省心。2.2 用DKMS还是手动编译手动编译make make install的方式最简单但有个致命问题Ubuntu内核一升级新内核里没有你编译的模块网卡又回到r8169问题复现。所以正确做法是用DKMSDynamic Kernel Module Support把驱动源码注册到DKMS框架里每次内核更新时自动重新编译安装。Ubuntu 20.04仓库里有dkms包但装它需要网络——而我们现在网卡不通这就成了鸡生蛋问题。我的处理思路是先用手机USB共享网络或者临时插一个USB网卡把dkms、build-essential、linux-headers-$(uname -r)这几个包装上然后再断网操作。如果实在没有任何备用网络也可以手动编译后把模块和配置写死但后续内核更新需要手动重来不推荐。下面流程按DKMS方式来写这是长期稳定的方案。2.3 驱动版本怎么选Realtek官网的驱动页面版本很多8.045、8.046、8.047、8.048、8.049、8.050、8.051都有。原则是不要盲目追新选和内核版本匹配的。Ubuntu 20.04内核5.4实测8.048.03和8.049.02这两个版本编译最顺8.051在5.4上会有implicit declaration of function的编译错误需要手动改代码。如果你内核是5.15比如Ubuntu 22.04那8.051反而更合适。所以先uname -r确认内核版本再选驱动版本。内核版本推荐驱动版本备注5.4.x (Ubuntu 20.04)8.048.03 / 8.049.02编译顺畅无需改代码5.15.x (Ubuntu 22.04)8.050.00 / 8.051.02新内核API适配更好6.x8.051.02需要较新驱动支持3. 编译环境准备与依赖安装3.1 确认网卡型号和当前驱动第一步永远是确认硬件。打开终端执行lspci -nn | grep -i ethernet输出里会看到类似Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168]的信息。方括号里的10ec:8168是厂商ID和设备ID后面配置黑名单时会用到。接着看当前加载的是哪个驱动lsmod | grep r816如果显示r8169说明用的内核自带驱动。再看详细信息和链路状态sudo ethtool enp3s0把enp3s0换成你实际的网卡名可以用ip a查看。重点看Speed、Duplex、Link detected三项。如果Link detected: no但网线插着基本可以确定是驱动问题。3.2 安装编译依赖需要装的东西有build-essential提供gcc、make、linux-headers-$(uname -r)内核头文件、dkms自动重编译框架。一条命令搞定sudo apt update sudo apt install -y build-essential linux-headers-$(uname -r) dkms这里有个常见坑linux-headers-$(uname -r)这个包名里的版本号必须和uname -r输出完全一致。如果你之前手动升级过内核但没装对应头文件这一步会报E: Unable to locate package。解决办法是先apt install linux-headers-generic或者用apt search linux-headers找到匹配版本。另一个坑是apt update需要网络如果网卡不通用手机USB共享网络临时解决或者挂载Ubuntu安装ISO作为本地源。提示如果apt完全用不了可以只装build-essential和dkms的离线deb包但linux-headers必须和内核版本严格匹配建议还是想办法临时联网。3.3 获取驱动源码Realtek官方驱动在官网下载页面文件名类似r8168-8.049.02.tar.bz2。如果目标机器没网在另一台机器下载后通过U盘拷过去。解压tar -xjf r8168-8.049.02.tar.bz2 cd r8168-8.049.02解压后目录里应该有src文件夹、Makefile、README等。先别急着编译看一眼src里的r8168_n.c确认版本号和你下载的一致。4. 编译安装与DKMS注册全流程4.1 先手动编译验证在注册DKMS之前建议先手动编译一次确认代码在当前内核下能过。进入源码目录cd src make clean make如果一切顺利最后会生成r8168.ko。如果报错常见的有两类一是error: implicit declaration of function pci_alloc_consistent这类说明驱动版本太老新内核移除了旧API需要换新驱动或手动改代码二是error: struct net_device has no member named trans_start同样是内核API变更导致。Ubuntu 20.04内核5.4配8.048/8.049基本不会遇到这些问题。编译成功后先别make install因为我们要走DKMS。如果手动编译就报错先解决编译问题再往下走否则DKMS注册也会失败。4.2 用DKMS注册驱动DKMS的标准做法是在/usr/src/下放源码然后dkms add/build/install。具体步骤sudo mkdir -p /usr/src/r8168-8.049.02 sudo cp -r /path/to/r8168-8.049.02/* /usr/src/r8168-8.049.02/然后创建DKMS配置文件/usr/src/r8168-8.049.02/dkms.conf内容如下PACKAGE_NAMEr8168 PACKAGE_VERSION8.049.02 BUILT_MODULE_NAME[0]r8168 DEST_MODULE_LOCATION[0]/kernel/drivers/net/ethernet/realtek AUTOINSTALLyes MAKE[0]make -C src CLEANmake -C src clean这里几个关键点BUILT_MODULE_NAME必须和编译出来的.ko文件名一致DEST_MODULE_LOCATION是模块安装路径放在realtek目录下和r8169同目录方便管理MAKE[0]指定编译命令因为源码的Makefile在src子目录里所以要-C src。注册并编译sudo dkms add -m r8168 -v 8.049.02 sudo dkms build -m r8168 -v 8.049.02 sudo dkms install -m r8168 -v 8.049.02每步都可能报错。dkms add报Error! Could not find module source directory说明路径不对dkms build报编译错误说明源码和内核不匹配dkms install报Module already in kernel说明内核里已有同名模块需要先处理。用dkms status可以查看当前状态。4.3 屏蔽r8169并配置自动加载驱动装好了但内核启动时还是会优先加载r8169因为它在内核树里。需要把r8169加入黑名单echo blacklist r8169 | sudo tee /etc/modprobe.d/blacklist-r8169.conf同时确保r8168开机自动加载echo r8168 | sudo tee /etc/modules-load.d/r8168.conf这两步做完重启后r8168会先加载r8169被屏蔽。但有个细节如果r8169已经被加载进initramfs光黑名单可能不够需要更新initramfssudo update-initramfs -u这一步很关键很多人漏掉后重启发现还是r8169就是因为initramfs里还带着旧模块。4.4 重启验证重启后执行lsmod | grep r816应该只看到r8168没有r8169。再看ethtoolsudo ethtool enp3s0Link detected应该变成yesSpeed显示1000Mb/s。dmesg | grep r8168能看到驱动版本和初始化日志。如果还是不行看dmesg | grep -i error有没有相关报错。5. 常见问题排查与避坑经验5.1 编译报错速查报错信息原因解决办法implicit declaration of function驱动版本老内核API变更换新驱动版本或手动补函数声明linux/headers not found内核头文件未装或版本不匹配apt install linux-headers-$(uname -r)Module r8168 not found in /lib/modulesDKMS install未成功检查dkms status重新buildERROR: modpost: missing MODULE_LICENSE源码缺少许可证声明在源码顶部加MODULE_LICENSE(GPL)make: gcc: Command not found编译工具未装apt install build-essential5.2 重启后网卡消失怎么办这种情况通常是r8168加载失败而r8169又被屏蔽了结果两个都没起来。排查步骤先dmesg | grep r8168看加载日志如果有Unknown symbol说明模块依赖没满足如果有probe failed说明硬件初始化失败。临时恢复网络可以sudo modprobe r8169先把旧驱动拉起来然后重新检查r8168的问题。另一个可能是/etc/modules-load.d/r8168.conf写错了模块名确认文件名和内容都是r8168。5.3 内核更新后驱动失效DKMS的意义就在这里。内核更新后dkms status应该显示新内核版本下r8168已自动编译安装。如果显示built但没installed手动sudo dkms install -m r8168 -v 8.049.02 -k $(uname -r)。如果显示编译失败通常是新内核API又变了需要更新驱动版本。建议在/etc/apt/apt.conf.d/里配置内核更新后自动触发DKMS不过Ubuntu默认已经处理了一般不用额外配置。5.4 实测中的几个小坑第一个坑make的时候如果之前编译过残留的.o文件可能导致链接错误先make clean再make。第二个坑DKMS的dkms.conf里MAKE[0]如果写成make而不是make -C src会报找不到目标。第三个坑有些主板BIOS里有个Wake on LAN选项开启后会影响驱动加载时序如果遇到休眠唤醒问题可以试着关掉。第四个坑ethtool显示的Speed如果还是100Mbps检查网线是不是超五类以上以及交换机端口是不是千兆。6. 这套方案的实际效果与后续维护我这台工控机按上面流程走完重启后ethtool显示Speed: 1000Mb/s、Duplex: Full、Link detected: yesiperf3打流能跑到940Mbps左右连续跑24小时没有断流。休眠唤醒测试了五次网卡每次都正常恢复。dmesg里r8168的初始化日志干净没有反复link up/down的刷屏。后续维护主要盯两件事一是内核更新后dkms status确认驱动跟着重编译了二是如果换主板或换网卡记得把旧的blacklist-r8169.conf和modules-load.d配置清理掉否则新网卡可能被误屏蔽。另外如果以后升级到Ubuntu 22.04或24.04内核变成5.15或6.8建议重新下载对应版本的r8168驱动不要直接沿用8.049新内核下可能有兼容问题。最后分享一个快速判断驱动是否生效的小技巧sudo lspci -k看网卡那一行Kernel driver in use后面显示的是r8168还是r8169一眼就能确认。这个命令比lsmod更直接因为它把设备和驱动对应关系列出来了。
返回列表