CentOS 7离线编译安装R8125 2.5G网卡驱动实战

CentOS 7离线编译安装R8125 2.5G网卡驱动实战
简介面向需要在无外网条件下为CentOS 7安装RTL8125网卡驱动的运维人员与开发工程师这份合集提供了从编译工具链到驱动加载的完整离线解决方案。资源包共52个文件约46MB包含gcc、gcc-c、glibc-devel等14个rpm离线依赖包以及r8125-9.007.01驱动源码和编译生成对象c/h/o/ko等配合autorun.sh、Makefile、readme等文件无需联网即可在目标机器上完成工具链部署、驱动编译与模块加载。作者针对官网驱动在旧内核环境的编译错误给出了修正版本同时整理了readme说明与依赖包清单可有效规避离线安装时缺少依赖或版本不匹配的常见问题。目前已有3257人学习下载适合内网服务器、工控设备等场景下的网卡驱动恢复是快速解决CentOS 7识别不到RTL8125网卡问题的实用资料。 新装了一台机器主板板载网卡是 Realtek 的 R8125 2.5G 网卡系统装的是 CentOS 7结果开机一看ip link只有 lo网口根本没起来。查了下硬件网卡芯片确实是 R8125问题就出在 CentOS 7 自带的 3.10 内核里没有这个网卡的驱动模块。更要命的是这台机器放在离线内网没法直接yum install gcc。而编译网卡驱动又必须要有 gcc、make、kernel-devel 这一整套工具链于是陷入了一个“没驱动所以没网络没网络又装不了编译工具”的死循环。这篇文章就把我这次完整的处理过程写出来怎么在离线状态下把 gcc 装好、怎么拿 R8125 驱动源码、官方驱动在 CentOS 7 上编译时会报哪些错、怎么改源码和 Makefile以及最后如何加载模块、配置网络。整个过程踩了不少坑希望帮你少走弯路。1. 问题定位R8125驱动和CentOS 7的兼容性困局1.1 R8125这个网卡为什么值得折腾R8125 是 Realtek 推出的 2.5Gbps 以太网控制器最近几年的中高端主板特别喜欢板载这颗芯片因为它在千兆和万兆之间找到了一个性价比很高的平衡点——不需要换交换机用普通的 Cat5e/Cat6 网线就能跑 2.5Gbps比传统千兆快 2.5 倍。但问题在于Linux 内核从 5.4 左右才开始原生支持 R8125 的较新版本。CentOS 7 用的内核是 3.10.0这已经是十年前的内核了不可能内置这个驱动。也就是说只要你的主板是 R8125 网卡装完 CentOS 7 之后必然面临“网卡不识别”的问题。有些朋友可能会说那直接换内核或者升级到 CentOS 8/9 不就行了?但很多生产环境、工控机、老旧项目就是锁死了 CentOS 7不能随便动系统版本。这种情况下老老实实编译驱动是唯一出路。1.2 离线装驱动卡住的其实是先有鸡还是先有蛋离线环境下装 R8125 驱动真正的难点不是编译本身而是“编译所需的工具链怎么来”。正常的在线安装流程非常简单yum install -y gcc gcc-c make kernel-devel离线环境下这行命令根本没法执行因为 yum 源指向的是外网。所以解决问题的关键顺序必须是这样先把 gcc、gcc-c、make 这些编译工具通过离线方式装进系统再准备与当前内核版本完全匹配的 kernel-devel内核头文件与编译脚本最后才能拿到 R8125 驱动源码去编译。这个顺序不能乱。很多人第一步就卡住了以为必须要网络才能装编译工具其实有两个非常成熟的办法可以解决我下面详细说。2. 离线安装gcc与编译工具链2.1 方案A用CentOS 7安装ISO搭建本地yum源这是最省事的方法前提是你手头有 CentOS 7 的安装镜像ISO文件。拿到 ISO 之后把它拷贝到目标机器的任意目录比如/root/然后挂载mkdir -p /mnt/cdrom mount -o loop /root/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom接着在/etc/yum.repos.d/下新建一个本地源配置文件cat /etc/yum.repos.d/local.repo EOF [local] nameLocal CentOS 7 DVD baseurlfile:///mnt/cdrom enabled1 gpgcheck0 EOF然后重新生成 yum 缓存yum clean all yum makecache此时再执行安装编译工具链的命令就能成功了yum install -y gcc gcc-c make这个方案的优点是不需要另一台联网 Linux 机器只需要一个 ISO 文件。缺点是 ISO 自带的软件包版本是镜像发布时的版本比如 CentOS 7.9 的 ISO 自带内核是3.10.0-1160.el7。如果你的系统在装完之后从没更新过内核那 kernel-devel 的版本刚好匹配但如果你之前手动yum update过内核那么 ISO 里的 kernel-devel 版本就跟当前运行内核不一致需要额外下载匹配版本。2.2 方案B在联网机器上提前下载RPM包如果你手头没有 ISO但有另一台可以联网的 CentOS 7 机器哪怕只是临时开一台云主机可以在那台机器上用yumdownloader把需要的 RPM 包全部拉下来拷贝到目标机器安装。联网机器上执行yum install -y yum-utils mkdir -p /tmp/rpms cd /tmp/rpms yumdownloader --resolve --destdir/tmp/rpms \ gcc gcc-c make kernel-devel kernel-headers--resolve参数会把所有依赖包一并下载比如 glibc-devel、libgcc、cpp、mpfr 等。下载完后把整个/tmp/rpms目录打包拷到目标机器。目标机器上安装时我建议用createrepo把这些 RPM 做成本地仓库而不是拿rpm -ivh *.rpm硬装。因为 RPM 之间存在依赖顺序硬装经常出现“装 A 需要 B装 B 又依赖 A”的闹心循环。cd /tmp/rpms yum install -y createrepo createrepo .然后写一个指向该目录的 repo 文件再yum installyum 会自动解决所有依赖顺序。2.3 最容易搞翻车的kernel-devel匹配问题我这里要单独用一小节强调一下 kernel-devel 的版本匹配因为这一步坑了无数人。编译内核模块时编译器需要用到当前内核的头文件和 Makefile这些内容就来自 kernel-devel。如果 kernel-devel 的版本跟当前运行内核不一致编译时会出现类似这样的报错/lib/modules/3.10.0-1160.el7.x86_64/build: No such file or directory或者更隐蔽的编译能通过但insmod时提示 version magic 不匹配version magic 3.10.0-1160.el7.x86_64 should be 3.10.0-1160.119.1.el7.x86_64所以动手之前先确认一下当前内核版本uname -r假设输出是3.10.0-1160.el7.x86_64那么你必须保证安装的 kernel-devel 也是3.10.0-1160.el7.x86_64。可以用下面命令核对rpm -q kernel-devel如果发现系统里没有 kernel-devel或者版本不对可以从 CentOS Vault 仓库http://vault.centos.org/下载对应版本的 RPM。Vault 里保留了历史版本的内核 RPM包括kernel-devel-$(uname -r).rpm。离线环境下用 U 盘把下载好的 RPM 拷进去rpm -ivh kernel-devel-xxx.rpm装上就行。提示尽量不要为了图省事装一个比当前内核更新的 kernel-devel然后yum update把内核刷上去。在离线环境下更新内核会带来一连串连锁依赖问题很容易让系统直接起不来。保持内核版本和 kernel-devel 一致才是正道。3. 驱动源码选择与官方驱动的“报错修补”3.1 驱动源码从哪拿R8125 驱动源码主要有两个渠道Realtek 官网提供的官方驱动压缩包文件名类似r8125-9.003.05.tar.bz2GitHub 上有人维护的镜像仓库比如搜索r8125就能找到不少仓库。我这次用的是官网的r8125-9.003.05版本。解压后目录结构大概是tar xjf r8125-9.003.05.tar.bz2 cd r8125-9.003.05 ls重要文件都在src/目录下核心源码文件是r8125_n.c编译入口是src/Makefile。另外根目录下有个autorun.sh脚本理论上自动执行make make install modprobe但在需要修改源码的场景下别直接用autorun.sh。我后面会解释为什么。3.2 编译必踩的坑C89标准与frame-larger-than这次在 CentOS 7 上编译我遇到了两个非常典型的报错都属于“官方驱动没考虑老内核、老编译器兼容性”的情况。第一个报错error: for loop initial declarations are only allowed in C99 or C11 mode原因是 CentOS 7 自带的 gcc 是 4.8.5内核 3.10 的 Kbuild 默认按 GNU C89 标准编译模块代码。而官方驱动里用到了 C99 风格的写法比如在for循环内部声明变量for (int i 0; i RTL8125_MAX_RX; i) { ... }这种写法在 C99 及以后的标准里没问题但老内核默认的 gnu89 标准不允许直接报错。第二个报错更隐蔽error: the frame size of 2208 bytes is larger than 1024 bytes这个报错跟内核的一个编译检查机制有关。内核在编译时会检查每个函数的栈帧大小默认阈值是 1024 字节。如果某个函数用掉的栈空间超过这个阈值就会报错。R8125 官方驱动在rtl8125_set_rx_mode等函数里申请了比较大的局部变量配合-O2优化后栈占用超过 1024触发检查报错。这两个问题虽然表现不同但解决方案都在src/Makefile里。打开这个文件找到KBUILD_CFLAGS相关的行追加关闭检查的选项KBUILD_CFLAGS -Wno-errorframe-larger-than KBUILD_CFLAGS -stdgnu99-Wno-errorframe-larger-than表示把栈帧超限的 warning 降级不当作 error-stdgnu99则明确指定用 GNU C99 标准编译解决for循环声明变量的报错。3.3 老内核兼容修改实例如果驱动源码版本较新可能还会遇到一些老内核根本没有的宏或函数。比如较新的 R8125 驱动为了支持 VXLAN/Geneve 等功能会用到一个叫NETIF_F_GSO_UDP_TUNNEL的特性宏。这个宏是内核 4.3 才引入的在 CentOS 7 的 3.10 内核里根本不存在编译时直接报error: NETIF_F_GSO_UDP_TUNNEL undeclared (first use in this function)解决办法是在r8125_n.c文件顶部的头文件包含区域后面手动补一个兼容宏#ifndef NETIF_F_GSO_UDP_TUNNEL #define NETIF_F_GSO_UDP_TUNNEL 0 #endif这样老内核编译时这个宏的值就是 0对应的代码路径相当于被禁用不影响网卡基本收发功能。如果你用的是比较老版本的驱动比如 9.003.05也可能遇到反过来的问题——老版本驱动没有考虑新内核但有ndo_set_vf_mac、ndo_get_stats64这些字段在新内核里存在、老内核不存在的结构体成员报错。处理思路一样都是通过#if LINUX_VERSION_CODE KERNEL_VERSION(x, x, x)加条件编译把新内核才有的代码段包起来。定位到报错行之后看看报错的结构体成员被哪些#if包着把版本判断阈值调低或者直接注释掉即可。4. 编译安装与网络配置全流程4.1 手动编译R8125驱动确认 gcc 和 kernel-devel 都就绪、源码修改完成后进入src目录手动编译cd r8125-9.003.05/src # 清理上次编译残留 make clean # 编译 make第一次编译建议不要直接跑./autorun.sh因为它内部会执行make clean然后直接make install一旦编译失败报错信息一闪而过容易看不清真正原因。手动make的好处是报错会留在终端里你可以一行行看。编译成功的话src目录下会生成r8125.ko文件ls -l r8125.ko然后执行安装make installmake install会把r8125.ko拷贝到/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/目录下并自动执行depmod -a更新模块依赖关系。如果你手动拷贝过模块文件别忘了补一次depmod -a4.2 加载模块、验证网卡状态安装完成后加载模块modprobe r8125然后看内核日志里有没有报错dmesg | grep -i r8125正常情况会出现类似r8125: 2.5Gbps Ethernet controller detected的日志。再用lsmod确认模块已加载lsmod | grep r8125这时候用ip link应该就能看到新出现的网卡接口了接口名可能是enp3s0、enp4s0、eth0之类取决于 PCI 总线位置ip link show看到接口出现后先手动把网口拉起来再用 ethtool 确认速率协商情况ip link set dev enp3s0 up ethtool enp3s0如果链路正常ethtool输出里Speed一项应该是2500Mb/s因为 R8125 本身就是 2.5G 网卡。4.3 配置静态IP让机器上网网卡识别成功且链路正常之后最后一步就是配置 IP。离线环境通常都是手工指定静态 IP我用 nmcli 配nmcli con add con-name r8125-eth ifname enp3s0 type ethernet \ ipv4.addresses 192.168.1.10/24 \ ipv4.gateway 192.168.1.1 \ ipv4.dns 223.5.5.5 114.114.114.114 \ ipv4.method manual nmcli con up r8125-eth如果你更习惯老一套的配置文件方式也可以直接写/etc/sysconfig/network-scripts/ifcfg-enp3s0cat /etc/sysconfig/network-scripts/ifcfg-enp3s0 EOF TYPEEthernet BOOTPROTOstatic NAMEenp3s0 DEVICEenp3s0 ONBOOTyes IPADDR192.168.1.10 NETMASK255.255.255.0 GATEWAY192.168.1.1 DNS1223.5.5.5 EOF systemctl restart network注意ONBOOTyes这一行很多新手配完网络重启后又不通了基本都是因为 ONBOOT 没设成 yes导致开机没有拉起网卡。配完用ping验证一下ping -c 4 192.168.1.1通了就说明驱动和网络配置都正常了。5. 排障实录常见问题速查与避坑经验5.1 编译与加载报错速查表我把这次遇到的和常见的问题整理成一张表方便你直接对照排查报错信息原因解决办法/lib/modules/xxx/build: No such file or directorykernel-devel 未安装或版本不对安装与uname -r完全一致的 kernel-develfor loop initial declarations are only allowed in C99...老内核默认 C89 标准Makefile 中追加-stdgnu99frame size ... larger than 1024 bytes函数栈帧超过内核限制Makefile 中追加-Wno-errorframe-larger-thanNETIF_F_GSO_UDP_TUNNEL undeclared老内核缺少新特性宏源码顶部补充#define NETIF_F_GSO_UDP_TUNNEL 0version magic xxx should be yyy编译模块时用的内核目录与当前内核不一致重新编译时指定正确的 KSRC或统一 kernel-devel 版本modprobe: ERROR: could not insert r8125: Exec format error模块格式与当前内核不匹配确认模块是用当前内核的 kernel-devel 编译的5.2 编译成功但网卡不亮怎么查模块加载成功、ip link也能看到接口但插上网线就是不通这种问题也遇到过几次。按这个顺序排查先看ethtool enp3s0的输出如果Link detected: yes说明物理链路正常问题在网络配置如果Link detected: no先强制指定速率协商ethtool -s enp3s0 speed 1000 duplex full autoneg on有些交换机的管理口或者老款百兆交换机对 2.5G 协商兼容性不好强制降到 1000M 甚至 100M 能解决一部分问题。注意这个设置在重启后会失效需要写进网卡配置文件或者设置开机自执行脚本。还有一点容易被忽略主板 BIOS 里可能默认把板载网卡关掉了或者开启了节能模式导致网卡处于休眠状态。进 BIOS 找到Onboard LAN、LAN Power Saving之类选项确认是 Enabled。最后dmesg | grep r8125仔细看一下有没有 DMA 相关报错或中断分配失败有些老主板在开启 IOMMU 的情况下会跟 R8125 驱动冲突可以在内核启动参数里临时加上iommusoft测试一下。5.3 离线场景下的几条实用心得最后分享几个实战经验都是反复踩坑后总结出来的。第一在整个离线环境里最值钱的东西是一个完整的、版本匹配的 RPM 包集合。建议在联网机器上下载 RPM 之后把所有包都打成一个 tar 包连同 R8125 驱动源码一起烧到 U 盘里。这样即使目标机器系统崩溃重装你也不用重新找包。第二如果你用 ISO 做本地 yum 源记得把挂载信息写进/etc/fstabecho /root/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom iso9660 loop,defaults 0 0 /etc/fstab否则重启后挂载丢失yum 源失效再想装别的包又得到处找源。第三不要轻易在离线环境下去执行yum update。更新内核之后新内核版本跟现有 kernel-devel 大概率对不上R8125 驱动模块很可能加载失败等于把自己逼回起点。宁愿保持内核版本不变只更新跟编译工具链相关的包。根据我个人的处理经验遇到这种离线装驱动的场景最重要的就是保持冷静、按顺序来先把工具链解决掉再处理内核头文件最后才是编译驱动的坑。这套流程跑通一遍之后其实也就半小时的事。以后再遇到别的网卡驱动离线编译套路是一样的只是源码里的报错不同排查思路完全可以复用。本文还有配套的精品资源点击获取

最新新闻

日新闻

周新闻

月新闻