ARTICLE DETAIL

资讯详情

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

银河麒麟V10下e1000e与rtl8125网卡驱动编译加载实战与DKMS自动化

银河麒麟V10下e1000e与rtl8125网卡驱动编译加载实战与DKMS自动化 简介本资源面向在银河麒麟V10国产操作系统上进行网卡适配的开发与运维人员提供e1000e与RTL8125两款网卡驱动的可编译源码解决系统与硬件适配中常见的编译报错与兼容性问题。压缩包共56个文件约483KB以c与h源码文件为主辅以makefile、readme、spec、updates等构建与说明文件覆盖驱动核心逻辑、头文件定义及编译配置。其中e1000e-3.8.4针对Intel 82573E、82574L等以太网控制器源码中已处理重复定义问题RTL8125Linux对应Realtek RTL8125B/C千兆网卡对函数参数做了适配调整便于在麒麟V10内核环境下顺利编译。目前已有2735人学习下载适合需要快速获取可用驱动源码、排查命名冲突与接口适配问题的开发者参考也可作为国产化平台网卡驱动移植的实践素材。1. 银河麒麟V10下e1000e与rtl8125驱动的编译现实为什么源码能过、insmod却翻车在银河麒麟V10上折腾网卡驱动的人多半遇到过同一个场景make一路绿灯insmod却甩出一串Unknown symbol或者Invalid module format。e1000e 和 rtl8125 这两款驱动尤其典型——前者是 Intel 千兆有线网卡的常青树后者是 Realtek 2.5G 网卡在国产化整机里出现频率极高的一颗芯片。标题里说的“能编译通过”其实只是第一关真正决定你能不能把网口跑起来的是内核头文件版本、vermagic校验、固件加载路径和内核配置这三四道暗门。这篇笔记面向的是手里有一台银河麒麟V10桌面版或服务器版都算、需要给 e1000e 或 rtl8125 重新编译驱动的一线运维和适配工程师。我会把源码从哪来、Makefile 怎么改、编译参数怎么对、加载失败怎么查按我实际踩过的顺序讲一遍新手能照着敲熟手能直接看参数边界。2. 编译之前先把内核底细摸清uname、headers 与 config 三件套2.1 为什么银河麒麟V10不能直接拿通用源码就编银河麒麟V10 的内核不是主线 vanilla kernel它带了自己的补丁集和配置裁剪。你从 Intel 或 Realtek 官网拉下来的驱动源码默认假设你跑的是标准内核Makefile里写的KERNELDIR往往指向/lib/modules/$(shell uname -r)/build这个路径在麒麟上大概率是空的或者指向一个不完整的头文件目录。更麻烦的是麒麟V10 不同小版本SP1、SP2、SP3的内核 ABI 有差异vermagic字符串里除了内核版本号还嵌了 SMP、preempt、module 校验等标志位任何一个对不上insmod直接拒绝。所以第一步不是急着make而是把当前运行内核的底细摸清楚。我一般会先跑三条命令uname -r看内核版本ls /lib/modules/$(uname -r)/build看头文件软链是否存在cat /boot/config-$(uname -r) | grep -E CONFIG_MODVERSIONS|CONFIG_MODULE_SIG看模块签名和版本校验有没有开。这三条命令的输出决定了后面 Makefile 怎么写、要不要关签名。# 查看当前运行内核版本 uname -r # 检查内核头文件目录是否存在正常应该是一个指向 /usr/src/ 下某目录的软链 ls -l /lib/modules/$(uname -r)/build # 查看内核配置中和模块加载相关的关键项 grep -E CONFIG_MODVERSIONS|CONFIG_MODULE_SIG|CONFIG_MODULE_SIG_FORCE /boot/config-$(uname -r)逻辑说明uname -r的输出是后面所有路径拼接的基准比如4.19.90-24.4.v2101.ky10.x86_64这种带麒麟标识的版本号。/lib/modules/$(uname -r)/build如果不存在说明你没装kernel-devel或者linux-headers包需要先用yum install kernel-devel-$(uname -r)补上。CONFIG_MODVERSIONSy意味着内核会校验模块符号 CRC你编译时用的头文件必须和运行内核完全一致CONFIG_MODULE_SIG_FORCEy则意味着未签名模块根本加载不了这种情况要么关掉强制签名要么自己签。参数说明CONFIG_MODULE_SIG_FORCE如果为yinsmod会直接报Required key not available这不是驱动代码问题是内核安全策略。麒麟V10 服务器版默认可能开启桌面版通常关。遇到这种情况临时方案是mokutil --disable-validation或者启动参数加module.sig_enforce0但生产环境要评估安全合规要求。2.2 拿到匹配的源码e1000e 和 rtl8125 的版本选择e1000e 的源码 Intel 官方在 SourceForge 上维护但版本更新很慢最新稳定版对 4.19 内核的支持是够的。rtl8125 的源码 Realtek 官网有单独的r8125包注意不是内核自带的r8169两者芯片 ID 有重叠但驱动架构不同混用会翻车。我一般会优先用麒麟V10 系统自带的kernel-devel里附带的驱动源码路径通常在/usr/src/kernels/$(uname -r)/drivers/net/ethernet/下如果里面有e1000e或r8169目录说明内核源码树是完整的可以直接在里面改省去版本匹配的麻烦。如果系统没带就从官方拉。e1000e 我常用e1000e-3.8.4.tar.gz这个版本rtl8125 用r8125-9.009.00.tar.bz2。解压后不要急着make先看src/Makefile里的KERNELDIR变量和EXTRA_CFLAGS麒麟V10 上经常需要手动指定KERNELDIR/lib/modules/$(uname -r)/build并加上-I$(KERNELDIR)/include。# 解压 e1000e 源码 tar -xzf e1000e-3.8.4.tar.gz cd e1000e-3.8.4/src # 查看 Makefile 中内核路径相关变量 grep -n KERNELDIR\|KERNEL_VERSION\|EXTRA_CFLAGS Makefile逻辑说明grep是为了确认 Makefile 是否硬编码了某个内核路径。如果看到KERNELDIR ? /lib/modules/$(shell uname -r)/build说明它自动取当前内核一般没问题如果写死了/usr/src/linux-headers-4.15.0-xx-generic这种 Ubuntu 路径就必须改成麒麟的实际路径。EXTRA_CFLAGS里如果有-DCONFIG_XXX之类的宏要对照/boot/config-$(uname -r)确认是否一致不一致会导致编译出的模块行为异常。参数说明KERNELDIR指向内核构建目录必须包含Makefile、include/、scripts/三部分。EXTRA_CFLAGS是传给编译器的额外宏定义麒麟V10 上常见需要加-D__KERNEL__和-DMODULE但现代内核 Makefile 会自动处理手动加反而可能冲突。3. 编译参数逐项拆解从 make 到 .ko 的每一步3.1 e1000e 的编译命令与关键参数e1000e 的编译相对标准进入src目录后直接make即可但有几个参数我建议显式带上。第一个是CFLAGS_EXTRA用来传内核版本兼容宏第二个是INSTALL_MOD_DIR决定make install时模块装到哪个子目录。麒麟V10 的depmod对模块路径敏感装错目录会导致modprobe找不到。# 进入 e1000e 源码目录 cd e1000e-3.8.4/src # 显式指定内核路径并编译CFLAGS_EXTRA 用于兼容麒麟内核的额外宏 make KERNELDIR/lib/modules/$(uname -r)/build \ CFLAGS_EXTRA-DKYLIN_V10_COMPAT \ -j$(nproc) # 查看生成的 .ko 文件 ls -lh e1000e.ko逻辑说明KERNELDIR显式指定避免 Makefile 取错路径。CFLAGS_EXTRA里的-DKYLIN_V10_COMPAT是我自己加的宏用来在代码里区分麒麟内核和主线内核的差异比如某些skb操作函数在麒麟 4.19 上签名不同。-j$(nproc)并行编译加速e1000e 源码量不大四核机器几秒就完。编译成功后e1000e.ko大概 300KB 左右用modinfo e1000e.ko可以看vermagic是否和uname -r一致。参数说明CFLAGS_EXTRA不是所有驱动 Makefile 都支持e1000e 的 Makefile 里有EXTRA_CFLAGS $(CFLAGS_EXTRA)这一行才有效。如果你的版本没有直接改EXTRA_CFLAGS变量。-j后面的$(nproc)是 CPU 核心数编译内核模块时并行度过高可能触发内存不足4GB 内存的机器建议-j2。3.2 rtl8125 的编译差异与固件依赖rtl8125 的编译比 e1000e 多一个坑它依赖固件文件rtl8125a-3.fw或rtl8125b-2.fw这些固件不在源码包里需要单独放到/lib/firmware/rtl_nic/下。如果固件缺失模块能编译能加载但网卡初始化会失败dmesg里报firmware: failed to load rtl_nic/rtl8125b-2.fw。我一般会从麒麟系统自带的linux-firmware包里找路径是/usr/lib/firmware/rtl_nic/如果没有就从 Realtek 官网的r8125包里翻通常藏在src/同级目录。# 进入 r8125 源码目录 cd r8125-9.009.00/src # 编译 r8125 模块注意这个 Makefile 用的是 KERNELDIR 变量 make KERNELDIR/lib/modules/$(uname -r)/build -j$(nproc) # 检查固件是否存在不存在则从系统 firmware 包复制 ls /lib/firmware/rtl_nic/ | grep 8125 # 如果没有从系统自带固件目录复制 cp /usr/lib/firmware/rtl_nic/rtl8125*.fw /lib/firmware/rtl_nic/ 2/dev/null逻辑说明make命令和 e1000e 类似但 r8125 的 Makefile 对KERNELDIR的默认值处理更激进有些版本会直接报错退出所以必须显式传。固件检查这一步不能省ls没输出就说明缺固件cp是从系统备用路径兜底。如果系统里也没有就得去 Realtek 官网下载rtl8125的完整包里面firmware/目录下有.fw文件。参数说明/lib/firmware/rtl_nic/是内核request_firmware的默认搜索路径之一另一个是/usr/lib/firmware/。麒麟V10 上这两个路径可能互为软链cp时注意不要覆盖已有文件。固件文件名必须和驱动代码里request_firmware调用的字符串完全一致rtl8125b 芯片对应rtl8125b-2.fwrtl8125a 对应rtl8125a-3.fw搞混了会加载失败。3.3 编译产物的验证modinfo 与 vermagic 检查编译完.ko之后不要急着insmod先用modinfo看三个字段vermagic、depends、firmware。vermagic必须和uname -r完全一致包括后面的 SMP、preempt 标志。depends列出模块依赖e1000e 通常依赖ptp和pps_corertl8125 依赖mii。firmware字段会告诉你这个模块需要哪些固件文件。# 查看 e1000e.ko 的模块信息 modinfo e1000e.ko | grep -E vermagic|depends|firmware # 查看 r8125.ko 的模块信息 modinfo r8125.ko | grep -E vermagic|depends|firmware # 对比当前内核版本 uname -r逻辑说明modinfo输出的vermagic如果和uname -r不一致比如内核是4.19.90-24.4.v2101.ky10.x86_64而模块是4.19.90-24.4.v2101.ky10.x86_64 SMP mod_unload modversions多出来的SMP mod_unload modversions是正常标志只要版本号主体一致就行。depends里的模块必须已经加载否则insmod会报Unknown symbol。firmware字段为空说明不需要固件有值则要确认文件存在。参数说明modinfo的-F参数可以单独取某个字段比如modinfo -F vermagic e1000e.ko只输出版本魔术串方便脚本比对。depends里的模块用lsmod | grep xxx确认是否已加载没加载就先modprobe它们。4. 加载与排错insmod 失败时先看 dmesg 的哪几行4.1 加载顺序与依赖模块处理e1000e 和 rtl8125 加载前先确认依赖模块就位。e1000e 依赖ptp和pps_core这两个模块麒麟V10 内核一般自带modprobe ptp pps_core即可。rtl8125 依赖mii同样modprobe mii。如果依赖模块不存在说明内核裁剪掉了需要重新编译内核或者找替代方案。加载顺序错了会报Unknown symbol in module这时候dmesg | tail -20会告诉你缺哪个符号。# 加载 e1000e 的依赖模块 modprobe ptp modprobe pps_core # 加载 e1000e 模块注意用 insmod 指定完整路径 insmod /path/to/e1000e.ko # 查看内核日志最后 20 行确认加载结果 dmesg | tail -20逻辑说明modprobe会自动处理依赖但前提是模块在/lib/modules/$(uname -r)/下有正确的modules.dep记录。手动编译的.ko不在这个体系里所以用insmod直接加载依赖模块手动modprobe。dmesg | tail -20是排错第一现场加载成功会看到e1000e: Intel(R) PRO/1000 Network Driver之类的版本信息失败则会有Unknown symbol或Invalid module format。参数说明insmod必须跟完整路径不能只写模块名。modprobe可以只写模块名但它会去/lib/modules/$(uname -r)/下找手动编译的模块需要先make install或者手动复制到/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/下再depmod -a。4.2 dmesg 关键行解读从报错到根因dmesg的输出里和驱动加载相关的关键行有几类。第一类是e1000e: probe of 0000:03:00.0 failed with error -X-X是错误码-5是 I/O 错误-12是内存不足-19是设备不匹配。第二类是rtl8125: Unable to load firmware rtl_nic/rtl8125b-2.fw这是固件缺失。第三类是module verification failed: signature and/or required key missing这是签名问题。第四类是disagrees about version of symbol这是vermagic或符号 CRC 不匹配。# 查看 dmesg 中和网卡驱动相关的行 dmesg | grep -iE e1000e|r8125|rtl8125|firmware|vermagic|signature # 如果报错是符号版本不匹配查看具体符号 dmesg | grep disagrees about version逻辑说明grep过滤出驱动名和关键词快速定位问题类型。disagrees about version of symbol后面会跟具体符号名比如disagrees about version of symbol skb_pull这说明编译时用的头文件和运行内核的符号 CRC 不一致需要重新编译确保KERNELDIR指向当前运行内核的头文件。参数说明dmesg -T可以显示人类可读时间戳方便对照操作时间。dmesg -w实时滚动适合一边插拔网卡一边观察。如果dmesg被刷屏用dmesg | grep -iE e1000e|r8125 | tail -50只看最后 50 行。4.3 网卡识别与 ifconfig 验证模块加载成功后用lspci -nn | grep -i ethernet确认网卡 PCI ID 被识别ip link show看有没有新的网络接口。e1000e 通常生成enp3s0这类 predictable namertl8125 生成enp4s0或eth0。如果ip link看不到接口但lspci能看到设备说明驱动 probe 失败回到dmesg看 probe 错误。如果接口存在但ip addr没 IP那是网络配置问题不是驱动问题。# 查看 PCI 网卡设备 lspci -nn | grep -i ethernet # 查看网络接口 ip link show # 查看接口详细信息和驱动绑定 ethtool -i enp3s0逻辑说明lspci -nn输出里的[8086:15b8]是 Intel 网卡 ID[10ec:8125]是 Realtek 2.5G ID。ip link show列出所有接口ethtool -i显示接口绑定的驱动名和版本如果driver: e1000e说明绑定成功。ethtool -i的firmware-version字段对 rtl8125 尤其重要能看出固件是否加载成功。参数说明ethtool需要单独安装麒麟V10 上yum install ethtool即可。ip link show的输出里BROADCAST,MULTICAST,UP,LOWER_UP表示接口已启用且链路正常DOWN表示网线没插或对端没通。5. 避坑与常见问题编译通过但加载失败的 5 个血泪记录5.1 现象insmod 报 Invalid module formatmodinfo 看 vermagic 却一致原因vermagic一致但insmod仍报格式错误多半是模块签名问题。麒麟V10 服务器版默认开启CONFIG_MODULE_SIG_FORCE未签名模块直接拒绝。modinfo不显示签名状态所以看起来一切正常。解决dmesg | grep -i signature确认是否签名报错。临时方案是启动参数加module.sig_enforce0永久方案是用内核自带的scripts/sign-file给模块签名需要生成密钥对并导入 MOK。5.2 现象e1000e 加载后网卡灯不亮lspci 能看到设备原因e1000e 驱动版本和网卡硬件不匹配。Intel 网卡分很多代e1000e 覆盖 I217、I218、I219 等但某些 OEM 定制版网卡需要更新的驱动版本。麒麟V10 自带的 e1000e 可能是 3.2.6而你的网卡需要 3.8.4 以上。解决ethtool -i enp3s0看driver和version如果版本低于 3.8.4从 Intel 官网拉最新源码重新编译。编译时注意Makefile里的EXTRA_CFLAGS要加-DCONFIG_E1000E_HW_RESET之类的硬件复位宏。5.3 现象rtl8125 加载成功但网速只有 100Methtool 显示 Speed 100Mb/s原因网线质量或对端设备限制。rtl8125 是 2.5G 网卡但需要 Cat5e 以上网线和支持 2.5G 的对端交换机。如果网线只有四芯或者对端是千兆口协商结果就是 100M 或 1000M。解决ethtool enp4s0看Supported link modes和Advertised link modes确认 2500baseT 是否在列。如果支持但没协商上用ethtool -s enp4s0 speed 2500 duplex full autoneg on强制指定。网线换 Cat6 以上。5.4 现象编译时 make 报错 “No such file or directory: /lib/modules/xxx/build/include/linux/kconfig.h”原因kernel-devel包没装或者版本和运行内核不匹配。麒麟V10 的kernel-devel包名带版本号比如kernel-devel-4.19.90-24.4.v2101.ky10.x86_64装错版本会导致头文件路径不对。解决yum install kernel-devel-$(uname -r)确保版本一致。如果 yum 源里没有对应版本从麒麟官方源或者安装 ISO 里找。装完后ls /lib/modules/$(uname -r)/build/include/linux/kconfig.h确认文件存在。5.5 现象rtl8125 加载后 dmesg 报 “rtl8125: probe of 0000:04:00.0 failed with error -22”原因-22是EINVAL参数无效。rtl8125 驱动 probe 时会对 PCI 配置空间做读写如果 BIOS 里 PCIe 配置有问题或者网卡被其他驱动比如r8169先绑定就会报这个错。解决lspci -k -s 04:00.0看当前绑定的驱动如果是r8169先rmmod r8169再insmod r8125.ko。如果r8169是内核自带且无法卸载把r8169加入黑名单echo blacklist r8169 /etc/modprobe.d/blacklist.conf然后update-initramfs -u或dracut -f。6. 进阶技巧用 DKMS 让驱动在麒麟V10内核升级后自动重编6.1 为什么手动编译的驱动活不过一次内核更新银河麒麟V10 的安全更新会推送新内核uname -r一变之前手动编译的.ko全部失效vermagic对不上网卡直接消失。生产环境如果靠人工重新编译每次更新都是一次事故。DKMSDynamic Kernel Module Support就是解决这个问题的它把驱动源码注册到系统里每次内核更新后自动触发重编译生成匹配新内核的.ko。6.2 把 e1000e 和 rtl8125 注册进 DKMS 的完整步骤DKMS 的核心是/usr/src/模块名-版本/下的源码和dkms.conf配置文件。我一般把源码复制到/usr/src/e1000e-3.8.4/和/usr/src/r8125-9.009.00/然后写dkms.conf。# 复制源码到 DKMS 标准路径 cp -r e1000e-3.8.4 /usr/src/e1000e-3.8.4 cp -r r8125-9.009.00 /usr/src/r8125-9.009.00 # 创建 e1000e 的 dkms.conf cat /usr/src/e1000e-3.8.4/dkms.conf EOF PACKAGE_NAMEe1000e PACKAGE_VERSION3.8.4 BUILT_MODULE_NAME[0]e1000e DEST_MODULE_LOCATION[0]/kernel/drivers/net/ethernet/intel/e1000e AUTOINSTALLyes MAKE[0]make KERNELDIR/lib/modules/${kernelver}/build CLEANmake clean EOF # 创建 r8125 的 dkms.conf cat /usr/src/r8125-9.009.00/dkms.conf EOF PACKAGE_NAMEr8125 PACKAGE_VERSION9.009.00 BUILT_MODULE_NAME[0]r8125 DEST_MODULE_LOCATION[0]/kernel/drivers/net/ethernet/realtek AUTOINSTALLyes MAKE[0]make KERNELDIR/lib/modules/${kernelver}/build CLEANmake clean EOF # 注册并编译安装 dkms add -m e1000e -v 3.8.4 dkms add -m r8125 -v 9.009.00 dkms build -m e1000e -v 3.8.4 dkms build -m r8125 -v 9.009.00 dkms install -m e1000e -v 3.8.4 dkms install -m r8125 -v 9.009.00逻辑说明dkms.conf里的BUILT_MODULE_NAME是编译出的.ko文件名DEST_MODULE_LOCATION是安装到/lib/modules/$(uname -r)/下的子路径。MAKE[0]里的${kernelver}是 DKMS 自动替换的变量指向当前要编译的目标内核版本。dkms add注册源码dkms build编译dkms install安装到内核模块目录并触发depmod。参数说明DEST_MODULE_LOCATION的路径要和内核自带驱动的路径一致否则modprobe可能优先加载旧驱动。AUTOINSTALLyes确保内核更新后自动重编。dkms status可以查看所有注册模块的状态dkms remove -m e1000e -v 3.8.4 --all卸载。6.3 验证 DKMS 是否生效模拟内核更新与回滚DKMS 装好后用dkms status确认两个模块都是installed状态。然后可以手动触发一次重编译来验证dkms build -m e1000e -v 3.8.4 -k $(uname -r)如果成功说明配置正确。更彻底的验证是装一个同版本的内核头文件包模拟内核更新看 DKMS 是否自动编译。如果失败/var/lib/dkms/e1000e/3.8.4/build/make.log里有完整编译日志。回滚也很简单dkms remove -m e1000e -v 3.8.4 --all会卸载模块并删除注册记录然后insmod内核自带的旧驱动即可。我一般会在 DKMS 装好后立刻做一次回滚测试确认后悔药有效再上生产。提示DKMS 编译依赖kernel-devel和gcc内核更新后如果kernel-devel没同步更新DKMS 会编译失败。建议把kernel-devel和kernel的更新绑定在一起或者用yum versionlock锁定内核版本。这套流程我在麒麟V10 SP2 和 SP3 上都跑过e1000e 3.8.4 和 r8125 9.009.00 是验证过能编译能加载的组合。内核头文件版本、固件路径、DKMS 配置这三块对上了网卡驱动就不会再是玄学。希望帮到你。本文还有配套的精品资源点击获取
返回列表