ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu 18.04离线编译安装RTL8125 2.5G网卡驱动实战

Ubuntu 18.04离线编译安装RTL8125 2.5G网卡驱动实战 你遇到过这种情况吗一台刚装好Ubuntu 18.04的机器系统起得干干净净但插上网线后指示灯不亮ifconfig里只有lolspci里明明能看到Realtek RTL8125这颗网卡就是没有驱动。更难受的是这台机器还放在内网环境没有网络就没有apt没有apt就装不上依赖装不上依赖就编译不了驱动——标准的死循环。这篇博客就是来破解这个死循环的在完全离线的Ubuntu 18.04上用预下载好的deb依赖包和Realtek官方RTL8125驱动源码徒手把这块有线网卡救回来顺便把编译、加载、开机自启、内核升级后丢驱动、Secure Boot拦截这些坑一个个排干净。1. 为什么RTL8125在Ubuntu 18.04上成了“隐形网卡”1.1 芯片很新内核太老RTL8125是Realtek在2019年前后推向市场的2.5Gbps以太网控制器具体型号常见RTL8125B、RTL8125BG走PCIe接口大量出现在中高端主板、工控机、小型NAS上。它比老大哥RTL8111/8168千兆要晚好几年Linux主线内核真正对它有完整驱动支持大概要到5.4版本左右而且早期还是融合进r8169驱动里逐步完善的。Ubuntu 18.04 LTS发布于2018年默认GA内核是4.15系列后续即使升级HWE内核一般也就到5.4。很多人安装系统时选的还是默认GA内核所以4.15版本里的r8169驱动只认RTL8168/8111这类设备ID看到RTL8125的设备IDPCI ID是10ec:8125根本不认识自然就不会给这个设备注册网络接口。lspci能列出来是因为PCI设备枚举是硬件层的功能跟驱动没关系真正要让网卡工作必须由内核里的net driver模块完成设备绑定和中断处理。这里打个比方lspci看到设备相当于物业知道这片商铺已经租出去了驱动没有加载相当于租客还没进来门面自然没法营业。ip link下面只有lo回环接口就是因为这张网卡还在“等待入驻”。1.2 离线安装的完整思路既然不能联网核心问题就变成在没有网络的情况下如何凑齐三样东西——编译工具链gcc、make、内核头文件linux-headers、硬件驱动源码。这三样缺一不可。整体方案是在另一台可以联网、而且系统和目标机保持一致的机器上把所有deb包用apt的download模式拉下来连同驱动源码一起塞进U盘再在目标机上离线用dpkg -i安装依赖最后手动编译驱动模块。整个流程分成两个阶段准备阶段和落地阶段。准备阶段只要把包备齐落地阶段基本就是执行一串命令的事。我见过不少新手卡在“用apt-get download下载依赖”这一步其实是因为对包的依赖关系不熟。后面的操作里我会给一个比较稳妥的下载方式直接把依赖树拉下来尽量避免漏包。2. 动手前必须搞定的三件事确认型号、准备依赖、拷贝源码2.1 目标机上确认网卡与内核版本在目标机上打开终端先跑两条最基础的命令uname -r lspci | grep -i ethernetuname -r会输出当前内核版本比如4.15.0-213-generic这个版本号后面下载linux-headers时会用到。lspci则能看到网卡型号。如果目标网卡是RTL8125输出类似这样03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8125 2.5GbE Controller (rev 05)如果系统里没有lspci说明pciutils这个工具没装。刚装好的系统离线状态下可以先用主板说明书或者网卡PCB上的丝印确认型号。另外一种笨办法是看/proc/bus/pci/devices文件但信息没有lspci直观。最省事的做法是在准备机上把pciutils的deb包也一并下载反正后面安装依赖时会一起装。我个人的习惯是顺便确认一下机器有没有其他可用的网口比如主板自带另一张Realtek RTL8111H千兆网卡。如果有问题就会简单很多先临时用那张网卡联网把依赖一次性装齐再回来编译RTL8125。但本文假设的是全网卡都不通的情况所以还是走全套离线流程。2.2 联网机器上把deb依赖一次打包好准备机建议也用Ubuntu 18.04系统版本越接近越好内核版本如果能和目标机一致就更理想。假设目标机内核是4.15.0-213-generic那么在准备机上执行mkdir -p ~/ubuntu18-debs cd ~/ubuntu18-debs sudo apt-get install --download-only -y build-essential linux-headers-4.15.0-213-generic libelf-dev dkms这里说明一下每条命令的作用。build-essential是编译工具链包含gcc、make、dpkg-dev等基础包linux-headers-内核版本是编译内核模块必需的头文件里面包含内核构建配置libelf-dev是编译某些内核模块时需要的ELF解析库少了它可能报找不到libelf.hdkms是后面做自动重建模块用的。这条命令不会真正在准备机上安装软件只是把deb包下载到/var/cache/apt/archives目录。下载完成后把它们统一打包sudo cp /var/cache/apt/archives/*.deb ~/ubuntu18-debs/ tar -czf ~/ubuntu18-debs.tar.gz ~/ubuntu18-debs如果archive目录里混有以前下载的其他软件包可以先执行sudo apt-get clean清空再执行download-only这样拷出来的deb包列表最干净。有一个非常容易踩的坑准备机和目标机的内核版本不一致。目标机上uname -r是4.15.0-213准备机上是4.15.0-112直接下载linux-headers-4.15.0-213-generic只要准备机的Ubuntu软件源里能搜到这个包就能下。如果搜不到说明这个内核版本不在当前源里要么换一个仍在维护的内核版本要么直接到packages.ubuntu.com上按版本号手动找deb包。提前核对清楚后面能少走很多弯路。2.3 拿到Realtek官方驱动源码驱动源码来源有两类官方和镜像。官方渠道是Realtek官网的下载中心在“Communications Network ICs / Ethernet Controllers / Software”分类下能找到RTL8125的Linux驱动文件名一般是r8125-9.004.01.tar.gz这种格式。下载时留意版本和日期尽量选最新稳定版。如果官网页面不好找或者下载速度不理想GitHub上有第三方镜像同步过RTL8125驱动源码搜索“r8125”即可。我自己用过的镜像只要压缩包里的版本号完整编译出来的模块都正常。官方源最稳妥镜像在应急时完全可用。驱动源码本身就是一个普通的tar.gz压缩包解压后目录结构大致如下r8125-9.004.01/ ├── README.md ├── autorun.sh └── src/ ├── Makefile ├── r8125.c ├── r8125.h └── ...里面没有复杂的构建系统就是Makefile加一个autorun.sh一键脚本。不过我在实操中更推荐分开执行make和make install这样每一步输出都能看到出了问题也好定位。3. 核心实战离线编译安装RTL8125驱动的完整流程3.1 离线安装编译依赖把U盘插到目标机上把deb包和解压后的驱动源码都拷贝到本地。假设所有deb包都放在/tmp/debs目录下执行cd /tmp/debs sudo dpkg -i *.deb如果dpkg提示依赖错误比如某些包安装顺序不对这时候不要慌。dpkg不是apt它不会自动解析依赖关系但会把当前能装的包尽量装完。此时再执行一次sudo dpkg -i *.deb第二次执行时因为第一批包已经装好大部分依赖关系已经满足往往就能全部通过。如果还有个别报错可以针对出错的包单独安装。装完后验证一下工具链gcc --version make --version ls /usr/src/linux-headers-$(uname -r)前两条确认编译工具可用第三条确认内核头文件目录存在。如果第三条提示No such file or directory说明linux-headers没装或者装的是其他版本需要回到第2.2节重新核对。这一步验证尽量一次做完不要直接进入编译否则后面报错容易混淆原因。3.2 编译驱动模块并加载依赖就绪后解压并进入驱动源码目录tar -xzf r8125-9.004.01.tar.gz cd r8125-9.004.01/src执行编译sudo make看到屏幕上滚过一堆gcc编译命令最后在当前目录生成r8125.ko文件就说明编译成功了。可以用ls -l r8125.ko确认文件存在和大小。接下来安装模块sudo make install这条命令会把r8125.ko复制到/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/目录下并自动运行depmod更新模块依赖。如果make install没有自动执行depmod可以手动补充sudo depmod -a sudo modprobe r8125modprobe加载模块后立刻查看效果ip link正常情况下输出里会出现eth0或者enp3s0这种新接口。再通过ethtool确认协商速率sudo ethtool enp3s0RTL8125协商速率应该显示2500Mb/s或者1000Mb/s具体看对端交换机和网线能力。能跑到2500说明驱动完全在正常工作。注意modprobe成功不等于网卡接口已经启用系统默认不会自动把新接口拉起来。还需要继续把它配置到可用的网络状态。3.3 让网卡真正工作起来接口配置Ubuntu 18.04下有两大网络配置体系桌面版用的NetworkManager服务器版用的netplan。不管哪种都要先弄清楚接口名。如果是PCIe位置命名常见enp3s0如果你在安装时手动改过命名规则也可能显示为eth0。临时测试连通性可以直接手动让接口起来并让DHCP分配地址sudo ip link set enp3s0 up sudo dhclient enp3s0如果网段有DHCP服务器这条命令能拿到IP。没有DHCP的话改静态IPsudo ip addr add 192.168.1.100/24 dev enp3s0 sudo ip route add default via 192.168.1.1但临时地址重启就会丢想永久生效服务器版要写netplan。编辑/etc/netplan/01-netcfg.yamlnetwork: version: 2 renderer: networkd ethernets: enp3s0: dhcp4: true应用配置sudo netplan apply如果是桌面版可以在“设置-网络”里直接添加有线连接也可以通过nmcli快速处理nmcli device status nmcli device connect enp3s0配置完后ping一下网关能通就说明网卡彻底救活。我第一次在实验室的机器上操作时走到这一步真的有种突然“解锁新设备”的感觉因为本来完全没网络的环境一瞬间就通了。3.4 用DKMS防止内核升级后驱动失效手动编译安装的模块是有保质期的一旦内核升级旧内核目录下的r8125.ko不会自动出现在新内核里。这是离线安装场景最容易出现的“回旋镖”问题——当时解决了过几个月一升级网卡又消失了。解决方案是用DKMSDynamic Kernel Module Support把驱动源码注册给系统让内核升级后自动重新编译模块。刚才的依赖包里已经带了dkms现在把源码放到/usr/src下并创建dkms.confsudo cp -r ~/r8125-9.004.01 /usr/src/r8125-9.004.01 sudo tee /usr/src/r8125-9.004.01/dkms.conf EOF PACKAGE_NAMEr8125 PACKAGE_VERSION9.004.01 BUILT_MODULE_NAME[0]r8125 DEST_MODULE_LOCATION[0]/kernel/updates/dkms AUTOINSTALLyes MAKE[0]make CLEANmake clean EOF然后依次注册、编译、安装sudo dkms add -m r8125 -v 9.004.01 sudo dkms build -m r8125 -v 9.004.01 sudo dkms install -m r8125 -v 9.004.01执行完dkms status可以看到模块状态正常情况下显示installed。之后每次内核升级DKMS都会自动为新内核重新编译r8125模块整个过程无需人工介入。强烈建议做完这一步否则下次内核更新十有八九要再折腾一次。需要留意的是DKMS在新内核里编译同样需要对应的linux-headers包。如果离线升级内核但没准备headers新内核起来后驱动还是会失败。所以内网环境里最好一次性把内核升级包和headers包都准备好。4. 踩坑实录编译失败、模块不加载、Secure Boot拦截4.1 编译报错的头号原因内核头文件没对上我见过最多的报错是这种make[2]: *** /usr/src/linux-headers-4.15.0-xxx-generic: No such file or directory. Stop.或者更直接的“linux/compiler.h: No such file or directory”。这类错误九成是linux-headers没装或者装的是另一个内核的headers和当前内核对不上。先跑uname -r确认实际内核版本再看/usr/src目录下有没有对应目录uname -r ls /usr/src/ | grep linux-headers两者对不上的话就把U盘里对应版本的linux-headers包重新安装。还有一个隐藏原因是/lib/modules/$(uname -r)/build软链接指向失效可以重新指向sudo ln -sf /usr/src/linux-headers-$(uname -r) /lib/modules/$(uname -r)/build老内核在编译时偶尔还会因为gcc版本太新导致“unrecognized command line option”的错误。Ubuntu 18.04默认的gcc 7一般没问题如果是从奇怪渠道拷贝过来的编译环境建议重新装一遍build-essential让gcc和make版本保持一致。4.2 模块加载成功但网卡不出现modprobe r8125没有报错但ip link里依然看不到新接口。这种时候先看两个地方设备是否被别的驱动抢占以及dmesg里驱动到底注册了什么。lspci -k | grep -A2 -i ethernet dmesg | grep r8125如果lspci -k显示“Kernel driver in use: r8169”说明系统内置的r8169驱动抢先绑定了RTL8125设备。老内核的r8169对RTL8125的支持并不完善虽然能枚举出设备但链路和速率都不正常。处理办法是把设备让给r8125sudo modprobe -r r8169 sudo modprobe r8125如果机器上只有RTL8125这一张有线网卡直接黑名单r8169更干净echo blacklist r8169 | sudo tee /etc/modprobe.d/blacklist-r8169.conf如果dmesg里完全没有r8125的日志说明模块根本没被加载或者设备ID没匹配上。有些驱动版本在Makefile里通过CONFIG_RTL8125宏控制支持列表可以检查一下Makefile里的相关配置。另一个可能原因是Secure Boot拦截看下一节。4.3 Secure Boot未关闭导致模块被拒在UEFI引导的机器上如果启用了Secure Boot系统只允许加载经过签名的内核模块。自己编译的r8125.ko没有任何签名加载时会被拒绝dmesg里通常能看到类似提示“Lockdown: modprobe: unsigned module loading is restricted”。检查Secure Boot状态mokutil --sb-state输出SecureBoot enabled就说明确实开着。解决方案有两个第一进BIOS关掉Secure Boot最直接重启后模块就能正常加载第二如果生产环境/合规要求不能关走DKMS签名流程生成密钥并注册到MOK数据库再给模块签名。流程比较繁琐离线场景下我一般不推荐搞。我在工控机上已经遇到很多次了新装机时忘了关Secure Boot装完驱动死活加载不上排查半天最后发现是签名问题。所以现在我的装机流程第一步就是进BIOS关Secure Boot见一次关一次能避免90%的第三方模块加载问题。4.4 常见问题速查表我把离线安装RTL8125过程中最常见的现象、原因和处理命令整理成一张表方便大家照方抓药。故障现象可能原因处理命令/操作make报No such file or directorylinux-headers未装或版本不匹配检查uname -r安装对应版本deb后重试makemake报找不到libelf.h缺少libelf-devdpkg -i libelf-dev*.deb后重新makemodprobe报Module not found模块路径未更新sudo depmod -a后再modprobe网卡接口不出现r8169抢先绑定modprobe -r r8169后modprobe r8125必要时blacklist r8169modprobe无报错但dmesg无日志Secure Boot拦截mokutil --sb-state确认BIOS关闭Secure Boot网卡能识别但速率只有1000Mb/s对端交换机、网线不支持2.5G换交换机端口确认网线为Cat5e以上dpkg -i *.deb报依赖错误dpkg不自动解析依赖再执行一次dpkg -i *.deb或按依赖顺序逐个安装这张表基本覆盖了我实操中遇到过的绝大多数问题。如果还碰到其他怪问题请优先看dmesg、journalctl -k这类系统日志很多线索都藏在里面。5. 折腾完后的几点实用建议5.1 备好“装机三件套”经过这一通折腾我现在在真实环境里的内网装机流程已经固定成了一套组合一个装了系统镜像的U盘一个塞满常用离线deb包的目录一个放驱动源码的文件夹。系统装完、驱动编译好之后顺手把当前的deb包再备份一次因为内核升级后大概率又需要新的headers包。这里分享一个小技巧在正常联网的机器上安装软件后/var/cache/apt/archives里会留下deb包定期打包存起来时间一长就是一套覆盖常见依赖的离线源。我曾经拿一台旧服务器积累的deb包直接给另一台同架构的新机器装齐了一堆基础软件整个过程基本没联网。这种“蚂蚁搬家”式积累在隔离网络环境下价值极高。5.2 临时网络救急USB共享上网如果目标机上有USB口还有一个更省事的临时网络方案用手机USB共享网络。手机连上USB线在手机“便携热点”里打开“USB网络共享”Ubuntu会把它识别成一张虚拟网卡使用的是系统自带的rndis_host驱动。有了网络离线方案就可以退居二线直接改成在线安装sudo apt update sudo apt install -y build-essential linux-headers-$(uname -r)我在实际工作中验证过Ubuntu 18.04对rndis的支持相当完善连接后基本插上就能拿到网段地址。这个方案唯一的硬性要求是机器必须有USB口并且系统内核没有精简掉驱动。服务器主板大多具备这个条件所以遇到棘手环境时这也可以作为破局手段。5.3 批量部署时直接拷贝.ko模块如果面对的是一排配置相同、内核版本也相同的机器并不需要每台都重新编译一遍。在一台机器上编译好r8125.ko之后直接把文件拷到其他机器上用insmod临时加载sudo insmod r8125.ko更规范一点放到模块目录并更新依赖sudo cp r8125.ko /lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/ sudo depmod -a sudo modprobe r8125这种批量部署方式非常适合工控机、实验室集群这种硬件型号高度统一的环境。前提是内核版本必须完全一致否则模块会因为版本不匹配被拒绝加载。稳妥起见批量部署前先在一台机器上验证modprobe正常再铺开到其他机器。机器数量特别多的话整个流程可以写成一个脚本参数传入内核版本和网卡设备ID从安装deb到编译驱动、modprobe、配IP全部自动完成。我手头就有一个这样的脚本放在U盘里到内网现场基本就是插上U盘跑一遍的事情。我在实际安装中最大的体会是离线装驱动并不难难的是提前准备好正确的依赖。只要deb包备对了整个编译过程反而比在线环境更稳定因为不会受到软件源更新或版本漂移的干扰。RTL8125这个网卡第一次折腾可能会花掉一两个小时但当你把依赖包和驱动源码都备好之后下一次同样的操作就是十分钟的事。这套离线流程跑通一次后面遇到任何内网、隔离环境里的网卡驱动问题你都不会慌了。
返回列表