☰
银河麒麟V10下e1000e与RTL8125网卡驱动编译与加载实战
2026/11/2 2:01:20 网站建设 项目流程

简介:面向在银河麒麟V10上进行网卡适配的运维与驱动开发人员,这份资源提供已在该系统上编译通过的e1000e与RTL8125两款网卡驱动源码,可解决国产化环境下Intel以太网控制器与Realtek RTL8125B/C千兆网卡因内核兼容性导致的编译失败、加载异常等问题。压缩包共56个文件,约483KB,以C源文件与头文件为主体,辅以Makefile、Kconfig相关脚本、README说明及spec打包配置,覆盖驱动核心逻辑、硬件抽象层与编译构建流程,便于按模块阅读和二次修改。资源已有2747人学习下载,说明其在国产系统网卡适配场景中具备一定参考价值。读者可从中获得可复用的编译基线,包括源码中重复定义的处理方式与函数参数调整思路,对照自身内核版本排查命名冲突与接口不匹配问题,减少从零移植的试错成本,适合具备一定Linux驱动基础、需要快速验证网卡可用性的技术人员参考。

1. 银河麒麟 V10 下把 e1000e 与 RTL8125 驱动编出来:一份能落地的源码包

手上有一批国产化环境要交付,机器装的是银河麒麟 V10,主板自带 Intel 千兆口,外加一张 RTL8125 的 2.5G 网卡。系统装完,lspci能看到设备,ip a里却只有 lo,网口死活起不来。这种场景在信创交付里太常见了——内核自带的驱动版本对不上,或者干脆没编进去。这份资源就是干这件事的:一套能在银河麒麟 V10 上编译通过的 e1000e 和 rtl8125 网卡驱动源码包,配套编译脚本和加载说明。它解决的不是“网卡怎么配 IP”这种上层问题,而是最底层的“驱动能不能编出来、能不能挂上去”。适合谁?做国产化适配的运维、做整机交付的实施、以及需要在麒麟上跑通网络链路的开发。如果你只是桌面用户插网线就上网,这份东西对你意义不大;但只要涉及定制内核、离线环境、批量装机,它就是那个能救命的黑匣子。

2. 先搞清楚驱动为什么编不过:内核头文件与源码树的三个错位

很多人拿到驱动源码,第一反应是make一把梭,然后被一屏报错劝退。血泪经验是:银河麒麟 V10 的编译失败,九成不是驱动代码本身的问题,而是编译环境和内核源码树没对齐。这一章先把“为什么编不过”讲透,再动手。

2.1 内核版本、头文件包、源码树三者的对应关系

驱动是内核模块,编译时要用到当前运行内核的头文件和配置。银河麒麟 V10 基于较新的内核分支,但不同小版本、不同架构(x86_64 / aarch64 / 飞腾 / 鲲鹏)对应的头文件包名和路径都不一样。常见做法是先确认三件事:uname -r拿到的运行内核版本、/lib/modules/$(uname -r)/build这个软链接指向哪里、以及/usr/src下到底有没有对应的源码目录。

# 确认运行内核版本 uname -r # 看 build 软链接指向,正常应指向 /usr/src/linux-headers-<版本> ls -l /lib/modules/$(uname -r)/build # 列出已安装的内核相关包 rpm -qa | grep -E "kernel-(devel|headers|source)"

这三条命令的输出要能对上号。如果build是个断链,或者指向的目录不存在,make必然报No such file or directory。参数说明:uname -r给的是运行内核,注意不是你安装的某个新内核;build软链接是内核模块编译的标准入口,驱动 Makefile 里的KERNELDIR默认就取这个路径。我一般会先跑这三条,确认环境干净再往下走,省得后面在报错里大海捞针。

2.2 驱动源码包里的 Makefile 该怎么改

e1000e 和 rtl8125 的源码包结构类似,顶层一个 Makefile,里面用KERNELDIR ?= /lib/modules/$(shell uname -r)/build指定内核路径。多数情况下这行不用动,但有两种情况必须改:一是交叉编译(比如在 x86 机器上给 aarch64 编),二是build软链接不可用、只能手动指定源码树。

# 顶层 Makefile 关键片段(示意) KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean

逻辑说明:-C $(KERNELDIR)让 make 切到内核源码树执行,M=$(PWD)告诉内核构建系统“外部模块在当前目录”。参数上,KERNELDIR可以用命令行覆盖,比如make KERNELDIR=/usr/src/linux-headers-xxx,这比改文件更灵活,也方便写进脚本。注意M=后面必须是绝对路径或$(PWD),写成相对路径在某些 make 版本下会翻车。

2.3 编译前必须装齐的依赖与 gcc 版本对齐

银河麒麟 V10 默认的 gcc 版本和内核编译时用的 gcc 版本如果不一致,会出现stack protector或module vermagic相关的警告甚至加载失败。常见做法是装gcc、make、kernel-devel、kernel-headers、elfutils-libelf-devel这几样,然后用cat /proc/version看内核是用哪个 gcc 编的,尽量对齐。

# 安装编译依赖(以 rpm 系为例) yum install -y gcc make kernel-devel kernel-headers elfutils-libelf-devel # 查看内核编译时的 gcc 版本 cat /proc/version

/proc/version里会带gcc version x.x.x字样,和你gcc --version的输出对比。差一个大版本通常没事,差太多就可能出vermagic不匹配。这一步是很多教程省略的,但恰恰是“编过了却加载不上”的根源。装完依赖再回头跑 2.1 的三条确认命令,环境才算立住。

3. 两个驱动分别编:e1000e 与 rtl8125 的编译参数和产物核对

环境对齐之后,编译本身反而是最顺的一步。但两个驱动的源码组织不同,产物名和加载方式也有差异,分开讲清楚,避免混着来。

3.1 e1000e:老牌 Intel 千兆口的编译与 .ko 产物确认

e1000e 是 Intel 千兆网卡的经典驱动,源码相对成熟,编译一般一次过。进到源码目录,直接make,成功后当前目录会生成e1000e.ko。

cd e1000e-src make -j$(nproc) # 确认产物 ls -l e1000e.ko modinfo e1000e.ko | head -20

-j$(nproc)用满 CPU 核数加速编译,对驱动这种小模块意义不大但没坏处。modinfo是关键核对步骤:看vermagic字段里的内核版本是否和uname -r一致,看description和author是否符合预期。如果vermagic对不上,说明 2.1 的环境没对齐,别急着加载,回去查。产物名必须是e1000e.ko,有些源码包会带版本后缀,加载时要用实际文件名。

3.2 rtl8125:2.5G 网卡的源码差异与编译注意点

rtl8125 的源码包通常来自厂商发布,目录里除了驱动还有dkms配置和README。编译命令一样是make,但要注意它可能默认去编r8125.ko而不是rtl8125.ko,名字别搞混。

cd rtl8125-src make -j$(nproc) # 产物通常是 r8125.ko ls -l *.ko modinfo r8125.ko | grep -E "vermagic|version"

逻辑说明:rtl8125 的模块名在源码里定义为r8125,这是厂商习惯,加载时用insmod r8125.ko而不是想当然的rtl8125。参数上,如果源码包带dkms.conf,说明它支持 DKMS 自动重编,但在离线交付场景里我一般不用 DKMS,直接手动编更可控。modinfo同样核对vermagic,另外看一眼version字段,方便记录交付的驱动版本。

3.3 用脚本把两个驱动的编译串起来

手工敲两遍命令容易漏步骤,尤其是批量装机时。写个简单脚本,把依赖检查、编译、产物核对串起来,交付时直接跑。

#!/bin/bash set -e KVER=$(uname -r) echo "当前内核: $KVER" # 检查 build 软链接 if [ ! -e /lib/modules/$KVER/build ]; then echo "错误: 内核源码树缺失,请安装 kernel-devel" exit 1 fi for dir in e1000e-src rtl8125-src; do echo "=== 编译 $dir ===" cd "$dir" make clean >/dev/null 2>&1 || true make -j$(nproc) ls -l *.ko cd .. done echo "编译完成,请用 modinfo 核对 vermagic"

脚本里set -e让任一步失败就退出,避免带着错误往下跑。make clean前加|| true是因为首次编译没有中间产物,clean 报错不算问题。这个脚本不负责加载,只负责“编出来并让你看到产物”,加载和验证放到下一章,职责分开,排错时好定位。

4. 加载、验证与开机自启:让网口真正跑起来

编出.ko只是第一步,加载不上、加载了不认、重启就丢,是三个不同层次的问题。这一章按“临时加载 → 验证链路 → 固化配置”的顺序走。

4.1 insmod 与 modprobe 的选择,以及依赖处理

临时验证用insmod最直接,指定绝对路径加载。但insmod不处理模块依赖,如果驱动依赖其他模块(比如某些内核的ptp),会报Unknown symbol。这时改用modprobe,前提是先把.ko拷到/lib/modules/$(uname -r)/extra/并跑depmod。

# 方式一:临时加载,适合快速验证 insmod /path/to/e1000e.ko insmod /path/to/r8125.ko # 方式二:走模块目录,处理依赖 cp e1000e.ko r8125.ko /lib/modules/$(uname -r)/extra/ depmod -a modprobe e1000e modprobe r8125

参数说明:depmod -a重建模块依赖索引,modprobe靠这个索引找模块和处理依赖。我一般验证阶段用insmod,确认没问题后再走modprobe固化。注意如果系统里已有同名驱动(比如内核自带的 e1000e),insmod会报File exists,得先rmmod旧的,或者用modprobe -r卸载,这一步顺序错了会白忙活。

4.2 用 dmesg 和 ethtool 确认驱动真的接管了网卡

加载完不等于网卡能用。看dmesg尾部有没有驱动打印的网卡识别信息,再用ethtool看链路状态,两步都过才算真接管。

# 看驱动加载日志 dmesg | tail -30 # 确认网口出现 ip link show # 看链路与速率协商 ethtool eth0

dmesg里应该能看到类似e1000e: eth0 NIC Link is Up或r8125: link up的字样。ethtool eth0的Speed字段对 rtl8125 应显示2500Mb/s(链路支持的前提下),对 e1000e 显示1000Mb/s。如果ip link里没有新网口,说明驱动没绑定上设备,回去看dmesg里的probe failed之类信息。这一步是验证的核心,别只看lsmod里有模块就以为成了。

4.3 固化:写进 modules-load 与处理内核升级后的重编

临时加载重启就丢,交付场景必须固化。简单做法是写/etc/modules-load.d/下的配置文件,让开机自动modprobe。但要注意:内核一升级,之前编的.ko的vermagic就对不上,加载会失败。所以固化方案里得包含“升级后重编”的提醒或脚本。

# 开机自动加载 cat > /etc/modules-load.d/net-drivers.conf <<'EOF' e1000e r8125 EOF # 确认模块文件在 extra 目录 ls -l /lib/modules/$(uname -r)/extra/

modules-load.d的配置在开机早期生效,比rc.local可靠。但内核升级后,/lib/modules/新版本/extra/下没有对应的.ko,自动加载就会失败。常见做法是把第 3 章的编译脚本保留在机器上,升级内核后手动跑一遍再depmod。这是离线交付里必须写进交付文档的一条,不然客户一升级内核就断网,回头还得找你。

5. 避坑清单:五个让驱动“编过了却用不了”的真实翻车点

这一章全是踩过的坑,按“现象 → 原因 → 解决”写,遇到对应症状直接对号入座。

5.1 现象:make 报 “No such file or directory: /lib/modules/xxx/build”

原因:kernel-devel没装,或者装的头文件版本和运行内核不一致,build软链接断链。解决:rpm -qa | grep kernel-devel确认版本,用uname -r对比,不一致就装对应版本;装完ls -l /lib/modules/$(uname -r)/build确认链接有效。这一步在 2.1 已经强调过,但实际交付里仍然是最常见的翻车点。

5.2 现象:编译通过,insmod 报 “Invalid module format”

原因:vermagic不匹配,通常是编译用的内核源码树和运行内核不是同一个版本,或者 gcc 版本差异过大。解决:modinfo xxx.ko | grep vermagic和uname -r对比,不一致就回到 2.1 重新对齐环境;gcc 差异大就装对应版本 gcc。别试图用--force强行加载,那是给自己埋雷。

5.3 现象:模块加载了,ip link 里却没有新网口

原因:驱动没绑定到设备,可能是设备被其他驱动占用(比如内核自带的同名驱动先接管了),或者 PCI ID 不在驱动支持列表里。解决:lspci -k看设备当前绑定的驱动,dmesg看 probe 失败原因;如果是旧驱动占用,先rmmod再加载新的;如果是 ID 不支持,得改源码里的 PCI ID 表重编,这属于进阶操作。

5.4 现象:rtl8125 加载后速率只有 1000Mb/s 甚至 100Mb/s

原因:链路协商问题,可能是网线、对端口、或者驱动默认的节能设置。解决:ethtool eth0看Supported link modes和Speed,确认对端支持 2.5G;用ethtool -s eth0 speed 2500 duplex full autoneg on手动指定;如果还不行,检查网线是否 Cat5e 以上。这个坑很玄学,有时候换根线就好了,但根因往往是协商策略。

5.5 现象:重启后网口消失,modules-load 没生效

原因:内核升级导致extra目录下的.ko版本不匹配,或者modules-load.d配置文件名/内容有误。解决:journalctl -b | grep -i modules-load看加载日志;确认/lib/modules/$(uname -r)/extra/下有对应.ko;内核升级后重跑编译脚本并depmod -a。这条是交付后最容易复发的问题,建议写进运维手册。

6. 进阶:把驱动编译做成可复用的离线交付包

单机编通只是起点,真正省事的是把“源码 + 编译脚本 + 依赖清单 + 验证脚本”打成一个离线包,换台机器解压就能跑。我一般会按下面的结构组织,交付时连同说明文档一起给。

目录/文件作用备注
src/e1000e/Intel 千兆驱动源码保持原始目录结构
src/rtl8125/2.5G 驱动源码含厂商 README
build.sh编译脚本含环境检查与产物核对
verify.sh加载后验证脚本dmesg + ethtool 检查
deps.txt依赖包清单按架构区分
README.md操作步骤与回滚说明含内核升级提醒

verify.sh可以写成这样,加载后自动跑一遍关键检查,输出结论:

#!/bin/bash # 加载后验证:检查模块、网口、链路 for mod in e1000e r8125; do if lsmod | grep -q "^$mod"; then echo "[OK] $mod 已加载" else echo "[FAIL] $mod 未加载" fi done for iface in $(ip -o link show | awk -F': ' '{print $2}' | grep -E '^(eth|enp)'); do echo "--- $iface ---" ethtool "$iface" 2>/dev/null | grep -E "Speed|Link detected" done

逻辑说明:先确认模块在lsmod里,再遍历所有以太网口看速率和链路状态。awk那行从ip -o link的输出里提取接口名,grep -E '^(eth|enp)'过滤掉 lo 和虚拟口。这个脚本不判断对错,只把关键信息打出来,让人一眼看出哪个口没起来。参数上没什么可调的,接口名规则因发行版而异,麒麟上常见eth和enp两种,都覆盖到。

打包时还有个细节:依赖清单要按目标架构分开写,x86_64 和 aarch64 的包名可能不同,混在一起装会失败。我一般会在deps.txt里用注释标清架构,交付前在目标机上跑一遍build.sh做冒烟测试。从那以后我每次做离线交付,都会强制走一遍“解压 → build → verify → 重启再 verify”的流程,少一步都可能在上线当天翻车。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询