简介在无外网依赖的服务器或内网环境中为CentOS 7手动编译安装Realtek R8125网卡驱动常常卡在缺少gcc/gcc-c工具链以及官网源码编译报错的问题上。这套资源包正是针对这两个痛点设计汇集了离线安装gcc与gcc-c所需的全部rpm依赖包并提供了修改后的驱动源码可有效规避官方版本在CentOS 7下的编译错误。压缩包共计52个文件以14个rpm离线包为核心辅以C语言源文件、头文件、预编译的.o/ko模块、Makefile构建文件与自动化安装脚本总大小46.09MB目录划分清晰便于按序操作。目前已有3268人次学习使用。通过阅读包内说明并执行autorun.sh可快速完成依赖安装、驱动编译加载及网络启用等全流程避免缺包、缺头文件等常见编译陷阱大幅提高离线装网卡驱动的整体成功率对运维人员、网络管理员及DIY玩家均具有实用参考价值。1. 一台离线 CentOS 7 装 R8125最难的从来不是驱动本身一台刚装完 CentOS 7 的离线服务器板载的 R8125 2.5G 网卡不出网。lspci 能看到设备系统里却没有任何驱动唯一的内网上行路径还进不去想 yum 装什么都装不了。这是很多人第一次碰 R8125 时的翻车现场难的根本不是芯片而是你连编译驱动的工具链都没有。CentOS 7 自带的 3.10 内核没有现成的 R8125 模块官方驱动源码得现场用 gcc 编成 .ko可离线机器上 gcc 和 gcc-c 往往都没装依赖包又卡在内网成了死循环。这篇文章顺着这条链路走一遍先用 repotrack 把离线编译工具链凑齐拿到官方 R8125 驱动源码处理它在较新内核下的编译错误最后加载并固化到系统重启不掉网。给正在机房、内网现场装机的你新手照着命令走熟手直接看第 4、5 章的报错与坑。2. 离线装 gcc 与 gcc-c用 repotrack 打一个完整的依赖包2.1 为什么要先装 gcc 和 gcc-c内核模块必须现场编译驱动不是下载完就能用的官方给的是 C 源码需要在目标机器上编译成 .ko 内核模块。编译动作本身依赖 gcc、make、kernel-devel、kernel-headers 这一套东西。标题里的 gcc 我理解为 gcc-c虽然网卡驱动是纯 C 写的但有些官方源码包里的辅助工具或 make 脚本会用到 C 编译器装齐了省得二次跑腿。离线环境最大的尴尬在于目标机上rpm -ivh xxx.rpm一下rpm 报一串Requires: libmpc.so.3之类的缺失。所以先解决的不是装包而是怎么把依赖闭环保出来。常见做法是找一台和这台机器同版本、能联网的 CentOS 7用它拉全依赖再打包拷过去。2.2 从联网机器全量拉依赖repotrack 比 yumdownloader 更保险yumdownloader 的--resolve会跳过本机已装的依赖包这在联网机器上很容易漏包——因为它认为这台机器已经满足依赖了。所以我习惯用 repotrack它不管本机装没装把每个包的所有依赖层层展开全部下载。yum install -y yum-utils mkdir -p /data/deps cd /data/deps repotrack -p /data/deps gcc gcc-c make kernel-devel kernel-headers glibc-devel libstdc-devel ls /data/deps | wc -l先装 yum-utilsrepotrack 是它自带的工具。-p /data/deps指定下载目录后面跟的包名列表就是要拉取的目标。gcc、gcc-c、make 是编译链主体kernel-devel 提供内核头文件和 Makefilekernel-headers 提供用户态和内核态共用的头文件glibc-devel 和 libstdc-devel 是 gcc 和 g 运行时缺一不可的依赖层。这里最关键的一步先到目标机器上执行uname -r把内核版本号抄下来。kernel-devel 必须和这个版本号完全一致否则驱动编译时用的头文件和你 boot 的内核对不上编出来的 .ko 加载时直接报 Exec format error。联网机器上这样下载指定版本repotrack -p /data/deps kernel-devel-3.10.0-1160.el7.x86_64目标机器的内核版本是多少kernel-devel 就必须是多少。下载完把整个 /data/deps 目录用 U 盘、内网拷到目标机目录里可能是几十个到上百个 rpm不用管谁是谁全带过去。2.3 目标机器安装rpm 依赖报错就再跑一遍到目标机上进到 rpm 包目录直接一把梭。cd /data/deps rpm -Uvh *.rpm-U是升级安装包没装过就等同安装装过会升级成仓库里新版本-v显示过程-h输出进度条。第一次执行中途大概率会停下来提示缺某个依赖包原因很简单rpm 是严格按命令行里通配符展开顺序逐个装的某些包的安装顺序会影响到后续包的依赖检查。这时候不要慌把报错里提到的包名记下来这个包其实已经躺在 /data/deps 里了只是还没轮上安装。直接再执行一次rpm -Uvh *.rpm或者单独装提示缺失的那几个包两三轮之后依赖树就捋顺了。不推荐--nodeps硬过后面编译时缺头文件更痛苦。装完后验证一下gcc --version g --version make --version ls /usr/src/kernels/$(uname -r)/include最后一行能列出目录内容说明 kernel-devel 和当前内核匹配编译环境这就齐了。2.4 备选方案手头有 CentOS 7 安装镜像就挂本地源如果手头有 CentOS 7 的 Everything 安装 ISO其实比 repotrack 更省事。ISO 本身就是完整的软件仓库把它挂载成本地 yum 源目标机就能直接 yum install。mount -o loop /opt/CentOS-7-x86_64-Everything.iso /mnt/repo cat /etc/yum.repos.d/local.repo EOF [local] namelocal baseurlfile:///mnt/repo gpgcheck0 enabled1 EOF yum clean all yum install -y gcc gcc-c make kernel-devel这个方案的优点是不需要第二台联网机器ISO 里自带完整依赖缺点是你得找得到对应版本的镜像而且服务器得能挂载光盘或 USB。两套方案选一个就行实测下来 repotrack 方案对大多数机房场景更通用。3. 拿下官方 R8125 源码包解压、目录结构与编译入口3.1 确认拿对包R8125 和 R8168 别拿混R8125 是一颗 2.5G 网卡芯片官方驱动包和 R8168 是两套独立的驱动树代码不能混用。下载时认准包名里带 r8125 字样的压缩包文件名一般是r8125-x.x.x.tar.gz这种格式。拿到 tar 包先别急着解压先用tar -tf不落盘查看内容确认包内有没有src/r8125.c这个核心文件。tar -tf r8125-*.tar.gz | grep -E src/Makefile|src/r8125.c|README这一步能看出两件事一是这个包到底是不是 r8125 的驱动源码二是包结构是否完整。如果 grep 出来只有几个 README 文件、没有 src 目录说明下载的很可能是个文档包或者拿错成了 r8168赶紧换。有些 ODM 主板上用的 RTL8125BG 等衍生型号驱动都共用这一套 r8125 源码不用额外区分。真正要区分的是网卡 PCI 设备 ID在目标机器上用lspci -nn看形如10ec:8125记下这个 ID后面验证驱动是否接管时要用。3.2 在 Linux 下解压别在 Windows 上先解压离线场景经常遇到一个问题压缩包是从内网 Windows 机器上下载的顺手就在 Windows 上用解压软件解压完再通过 FTP 传到 Linux。这样做十有八九会出问题——tar 包里的文件权限位全丢autorun.sh没了可执行权限甚至文本文件被转成 CRLF 换行make 脚本读到一半报错。正确做法是把原始 tar 包整包拷到 Linux 机器上用 tar 自己解压。tar 包在拷贝过程中要选择二进制模式传输不要用 ASCII 模式否则一样会坏掉。chmod 755 r8125-*.tar.gz tar xvf r8125-*.tar.gz cd r8125-*/ chmod x autorun.shtar xvf解压后源码包内的目录权限和生产环境需要的可执行位都能保留。如果手头确实只有 Windows 解压过的版本那就用chmod x补权限再用dos2unix autorun.sh修换行符这是补救做法能少踩一个算一个。3.3 先看目录结构和编译入口autorun.sh 与 src/Makefile解压后目录里最重要的两个东西autorun.sh是官方给的自动安装脚本src/是真正的内核模块源码。自动脚本做的事本质上是先把内核里旧驱动卸载进入 src 目录执行 make再把编出来的 r8125.ko 拷贝到模块目录并加载。听起来一气呵成但现场我不推荐直接跑 autorun.sh原因很简单只要 make 报一个错你根本看不清楚它死在哪个环节。我一般直接进 src 目录手动编每个步骤都在自己眼皮底下过。cd src ls -l Makefile r8125.cMakefile 是编译入口r8125.c 是驱动主体几千行的规模。Makefile里最关键的变量是 KSRC它指向内核源码树路径。官方包默认值经常写得不对这是后面编译报错的头号来源。先看两眼默认配置心里有个底然后进入下一章的修改环节。4. 修改官方驱动错误内核接口变了编译报错这样定位和改4.1 官方驱动在 CentOS 7 上编译的三类典型报错先泼一盆冷水官方驱动源码不等于解压就能编译过。它的目标内核版本往往比你的系统新或者比你的系统旧两边不对齐就会报错。在 CentOS 7 上编译常见的报错大致三类先对号入座再动手。报错片段原因解决方向Cannot find kernel headers/build: No such file or directoryMakefile 里 KSRC 变量指向的内核头文件目录不存在显式指定 KSRC 为当前内核对应的 /usr/src/kernels 路径error: assignment ... from incompatible pointer type驱动的回调函数原型和新内核结构体定义不匹配定位到报错的赋值行删除或改写对应回调error: implicit declaration of function/redefinition of ...驱动用了旧内核 API新内核已换写法或改名把旧 API 换成新写法比如 init_timer 换 timer_setup这里有个特别容易迷惑人的点CentOS 7 的内核版本号显示3.10.0-1160.el7.x86_64但它 backport 了大量新内核接口你要是真按老内核去改反而会改错方向。判断标准只有一个编译器报什么就按什么改你盯着 system 版本号猜不算数。4.2 修改点一Makefile 显式指定 KSRC解决找不到内核头文件这是出现频率最高的报错现象是 make 一开始就停住提示找不到内核构建目录。uname -r ls -ld /usr/src/kernels/$(uname -r) ls -ld /lib/modules/$(uname -r)/build第一行确认当前内核版本第二行看 /usr/src/kernels 下有没有对应的目录第三行看 /lib/modules 下的 build 软链接有没有断。CentOS 7 装好 kernel-devel 后这两个位置应该都能访问且最终指向同一套内核源码树。然后进入驱动源码目录执行编译并显式传入 KSRCcd /root/r8125-*/src make clean make KSRC/usr/src/kernels/$(uname -r)make KSRC...的意思是覆盖 Makefile 里默认的 KSRC 变量让它指向当前内核的头文件目录。如果你不想每次敲一长串也可以先改 Makefile找到KSRC ?那一行把路径改成/lib/modules/$(uname -r)/build保存后直接make。两个路径是软链接关系效果一样。4.3 修改点二适配新内核处理结构体成员和接口签名KSRC 修好之后真正的重头戏来了。编译报错如果停在src/r8125.c里定位方法很简单报错信息会提示是哪一行、哪一个函数、什么类型的错误。先把所有可疑的旧接口一次找出来。grep -n init_timer\|ndo_udp_tunnel_add\|get_regs_len\|get_settings src/r8125.c | head -30搜索出来的每一行都可能是编译报错点。最经典的是init_timer。老内核里初始化定时器这样写/* 旧内核4.x 及更早写法 */ init_timer(tp-timer); tp-timer.function rtl8125_timer_callback; tp-timer.data (unsigned long)tp; add_timer(tp-timer);新内核里init_timer被删掉换成了timer_setup而且回调函数原型也不一样了。旧回调从data参数里取出私有指针新回调要用from_timer宏从struct timer_list *反推容器结构体地址。/* 新内核 5.x 写法 */ static void rtl8125_timer_callback(struct timer_list *t) { struct rtl8125_private *tp from_timer(tp, t, timer); /* ... */ } timer_setup(tp-timer, rtl8125_timer_callback, 0); add_timer(tp-timer);from_timer(tp, t, timer)的意思是根据 timer_list 指针 t计算出它所在结构体 rtl8125_private 的首地址timer是结构体里 timer_list 成员的名字。这个宏是新内核的标准姿势比当年用container_of手写干净得多。再一类报错是net_device_ops结构体里有成员在新内核被删了或被改名了。报错长这样error: struct net_device_ops has no member named ndo_udp_tunnel_add。处理办法是打开 src/r8125.c找到 net_device_ops 赋值的位置把报错的那一行注释掉或删掉。这类回调大多是可选的辅助功能删掉不影响网卡基本收发。4.4 改完后重新编译命令、参数与产物确认改完代码重新编译。这次应该能一路编到底。cd /root/r8125-*/src make clean make KSRC/usr/src/kernels/$(uname -r) ls -l r8125.ko file r8125.komake clean把上一次半成品目标文件清掉防止旧的 .o 混进新编译结果。file r8125.ko拿来确认产物格式正常输出是ELF 64-bit LSB relocatable, x86-64。如果输出的是stripped或者奇怪的格式说明编出来的不是内核模块基本是 KSRC 指错了或者内核头文件不对一行行接着查。到这一步r8125.ko 已经躺在 src 目录里。后面就是加载、验证和固化。5. R8125 安装高频坑排查从 modprobe 失败到重启掉网5.1 手动加载前先做的三件事rmmod、blacklist、depmod编出 r8125.ko 之后不要急着 insmod先把环境捋干净。这三个动作按顺序执行能避免大量玄学问题。rmmod r8169 2/dev/null echo blacklist r8169 /etc/modprobe.d/blacklist-r8169.conf depmod -a modprobe r8125 ip link第一行rmmod r8169把内核里可能占着这块网卡的老驱动卸载。CentOS 7 的 3.10 内核里 r8169 对 RTL8125 的识别能力很弱但如果你换过内核或者装过额外驱动它可能已经抢占了设备。第二行写 blacklist 配置防止 reboot 后 r8169 又把设备抢走。第三行depmod -a重建模块依赖关系因为新 r8125.ko 还没被内核模块系统认识。第四行modprobe r8125让它按 modules.alias 找驱动并加载。最后ip link看网卡设备有没有出现。如果加载失败按顺序看这三条输出能定位九成问题lspci -nnk | grep -A2 -i ethernet dmesg | grep -iE r8125|r8169 ls -l /sys/bus/pci/devices/*/driver 2/dev/nulllspci 看网卡设备 IDdmesg 看内核日志里驱动的报错最后一条看当前是哪个驱动接管了这个 PCI 设备。5.2 坑一modprobe 报 Exec format error现象insmod r8125.ko或modprobe r8125直接报Exec format error。原因r8125.ko 编译时用的内核头文件和你当前 boot 的内核版本不一致或者编译器版本差太多。最常见的是在 A 机器上编好 .ko拷贝到 B 机器去加载只要两台机器的内核版本、编译工具链不匹配这个错误必现。解决回到目标机器上用目标机器的内核头文件重新编译。uname -r确认版本ls /usr/src/kernels/$(uname -r)确认头文件存在然后重新执行make KSRC/usr/src/kernels/$(uname -r)。编完就在本机加载不要跨机器拷贝 .ko。5.3 坑二lspci 看得到网卡ip link 看不到现象lspci -nn里明明有 R8125 设备但ip link输出里没有任何对应网卡。原因驱动模块没有成功加载或者加载了但 pci 设备 ID 不匹配。有些老版本的官方驱动包 pci_device_id 表里没加新修订版网卡的 IDprobe 阶段直接放弃。解决先dmesg | tail -50看有没有 r8125 的报错日志。如果是no device found一类提示基本就是驱动不认识这个 PCI 设备 ID把lspci -nn输出的 ID 记下来去换新一版官方驱动包。如果 dmesg 里根本没 r8125 的日志说明模块没加载回到 5.1 的顺序重新走。5.4 坑三协商速率只有 1000Mb/s现象网卡能通但 ethtool 看到 Speed 是 1000Mb/s不是期望的 2500Mb/s。原因不一定是驱动问题。2.5G 需要网线两端设备都支持 2500 协商对端交换机口如果只支持千兆或者网线质量不行协商结果就是 1000。驱动层面一般不会限制这个速率。解决先换根网线、换交换机上支持 2.5G 的口再测。如果确定对端支持 2500再查 ethtool 里的 advertised link modes。不建议上来就ethtool -s 网卡名 speed 2500 duplex full强制这个命令在链路不可靠时会把网络直接打掉还不如让它自动协商。5.5 坑四重启后网卡又消失或换成了老驱动现象刚装完一切正常一 reboot网卡要么没了要么被 r8169 接管要么系统根本起不来少见。原因r8125.ko 没有进入内核模块持久化目录系统重启后没有加载它或者内核里 r8169 比 r8125 先 probe把设备绑定走了。解决把 r8125.ko 放进标准模块目录刷新依赖重建 initramfs。这一套下来才能保证重启后驱动依然生效具体命令在下一章给出。注意 CentOS 7 必须用 dracut 重建 initramfs用 mkinitrd 的老一套在这版本上已经不好使了。5.6 坑五make 时报找不到 build 目录或 stdio.h现象编译时提示/lib/modules/3.10.0-1160.el7.x86_64/build: No such file or directory或者干脆报stdio.h: No such file or directory。原因build 软链接断了或者 kernel-devel、glibc-devel 没装全。有人只装了 kernel-devel漏了 glibc-devel结果编译头文件缺一大片。解决回到第 2 章用 repotrack 把 glibc-devel、kernel-headers 一并拉下来装上。ls -l /lib/modules/$(uname -r)/build看软链是否存在如果指向的目录不存在问题就出在 kernel-devel 版本不匹配上别犹豫重装对应版本。6. 用 ethtool 和 dmesg 验证网卡把驱动固化到开机6.1 用三条命令确认驱动真正生效加载完成后别急着配 IP先确认驱动真的接管了网卡。三条命令足够。ethtool -i 网卡名 ethtool 网卡名 dmesg | grep r8125网卡名用ip link查可能是 eth0也可能是 enp3s0 这种带 PCI 位置的名字。ethtool -i看 driver 一栏是不是 r8125version 是官方驱动的版本号ethtool不带 -i 看 Speed 协商结果Link detected 必须是 yesdmesg里应该有 r8125 初始化链路和 link up 的日志。还有一个确认方式ls -l /sys/bus/pci/devices/0000:03:00.0/driver输出指向的目录名如果是 r8125说明这块网卡百分百由 r8125 驱动接管。如果指向 r8169说明 5.1 那套顺序没走完。6.2 固化安装dracut 重建 initramfs 与网卡自启配置验证通过后把驱动固化进系统做到重启不掉网。下面这套脚本我每次装完都会跑一遍DRV_DST/lib/modules/$(uname -r)/updates/r8125.ko mkdir -p /lib/modules/$(uname -r)/updates cp /root/r8125-*/src/r8125.ko $DRV_DST depmod -a echo blacklist r8169 /etc/modprobe.d/blacklist-r8169.conf echo r8125 /etc/modules-load.d/r8125.conf dracut -f /boot/initramfs-$(uname -r).img $(uname -r)mkdir 先建目录cp 把驱动拷贝到 updates 目录这是外部模块的标准落位depmod 会扫描并把它写进 modules.dep。blacklist r8169 确保老驱动不再抢设备modules-load.d 让系统启动时自动加载 r8125最后 dracut 把模块塞进 initramfs这一步直接解决 reboot 后驱动消失的坑。网卡自启还要配 ifcfg 文件按实际网卡名建一个# /etc/sysconfig/network-scripts/ifcfg-enp3s0 TYPEEthernet BOOTPROTOdhcp NAMEenp3s0 DEVICEenp3s0 ONBOOTyes如果这台机器走静态 IP把 BOOTPROTO 改成 none再加 IPADDR、NETMASK、GATEWAY、DNS1 几行就行。文件放在 /etc/sysconfig/network-scripts/ 下NetworkManager 重启后会自动接管。装完驱动的习惯动作我永远是先备份 /boot 下的 initramfs 再动 dracut新 initramfs 万一有问题还能用旧的救回来。R8125 这套流程跑过几次后其实不难难的是第一次面对报错时不知道往哪个方向查。希望这篇能把离线装 R8125 的门槛降下来希望帮到你。本文还有配套的精品资源点击获取