资讯详情

资讯详情

银河麒麟V10网卡驱动编译通过却不通?e1000e与RTL8125排查指南

简介面向在银河麒麟V10上进行网卡适配的运维与驱动开发人员这份资源提供已在该系统上编译通过的e1000e与RTL8125两款网卡驱动源码可解决国产化平台下Intel与Realtek网卡无法正常加载、编译报错等适配难题。压缩包共56个文件以C源文件与头文件为主体辅以Makefile、README、spec及校验文件等整体约483KB结构完整、便于直接编译验证。资源中针对源码重复定义与函数参数做了适配调整读者可据此理解内核兼容性修改思路快速完成编译、加载与网卡功能验证。目前已有2747人学习下载适合需要排查驱动兼容问题或积累国产系统移植经验的技术人员参考。1. 装完驱动网卡还是没起来银河麒麟 V10 上 e1000e 与 RTL8125 编译通过却不通的坑在银河麒麟 V10 上折腾网卡驱动最让人抓狂的不是编译报错而是make一路绿灯、insmod也没报错结果ip link里压根看不到那块网卡或者看到了却死活拿不到地址。e1000e 和 RTL8125 这两颗芯片在国产化桌面和工控机上出现频率极高前者是 Intel 千兆有线后者是 Realtek 2.5G 有线很多整机出厂预装的驱动版本偏老或者内核里只带了半残的模块于是大家第一反应就是去下源码自己编。编过的人都知道银河麒麟 V10 的内核是深度定制过的头文件路径、CONFIG_*开关、GCC 版本都跟上游主线有出入编译通过只是万里长征第一步。这篇笔记面向的是已经卡在“驱动装上了但网卡不工作”这一步的开发者也适合刚接手国产化适配、被网卡问题反复折腾的新手下面按故障现象一层层往下拆。2. 编译阶段就翻车内核头文件与 GCC 版本对不上导致的报错银河麒麟 V10 上编 e1000e 和 RTL8125十有八九会先栽在编译环节。报错五花八门但根子基本就两个一是找不到当前运行内核对应的头文件二是编译器版本和内核构建时用的不一致。这一章把最常见的几类编译报错摆出来逐个说清触发条件和处理办法。2.1 报错 “找不到 kernel headers”/lib/modules/$(uname -r)/build 是空链接最典型的报错长这样make: *** /lib/modules/5.4.18-xxx-generic/build: No such file or directory. Stop.或者进到驱动目录执行make时提示Kernel build directory not found。这个报错的触发条件很明确系统里装了内核但没装与之完全匹配的linux-headers包或者/lib/modules/$(uname -r)/build这个软链接指向了一个不存在的目录。银河麒麟 V10 的内核版本号带厂商后缀很多人直接apt install linux-headers-$(uname -r)会失败因为软件源里根本没有这个精确版本。先确认现状# 看当前运行内核版本 uname -r # 看 build 链接指向哪里是否断链 ls -l /lib/modules/$(uname -r)/build # 查软件源里有哪些可用的头文件包 apt list --installed 2/dev/null | grep -i headers apt-cache search linux-headers | grep $(uname -r)如果build是断链或者apt-cache search查不到精确版本常见做法是去系统安装镜像或厂商提供的软件源里找对应版本的linux-headers和linux-devel包手动安装。装完后重新确认链接# 安装匹配的头文件包后重建 build 软链接路径按实际内核版本替换 sudo ln -sfn /usr/src/linux-headers-$(uname -r) /lib/modules/$(uname -r)/build # 验证头文件目录里确实有 Makefile 和 include ls /lib/modules/$(uname -r)/build/Makefile这里ln -sfn的-f是强制覆盖已有链接-n是把已存在的目录链接当普通文件处理避免在目标目录里再建一层。链接修好后make才能找到内核构建树。需要提醒的是头文件版本必须和uname -r完全一致差一个小版本号都可能编出加载不上的模块这是后面insmod报Invalid module format的伏笔。2.2 报错 “error: implicit declaration of function”GCC 版本与内核构建链不匹配第二类高频报错是编译中途大量函数隐式声明警告升级成错误error: implicit declaration of function ‘xxx’; did you mean ‘yyy’? error: ‘struct xxx’ has no member named ‘yyy’这类报错看着像驱动源码写错了其实多半是编译器版本和内核构建时用的 GCC 不一致。银河麒麟 V10 不同更新批次带的内核可能是用 GCC 7、GCC 8 或更高版本编的而系统默认gcc可能被切到了别的版本。内核模块对编译器版本敏感头文件里的内联函数、宏展开在不同 GCC 下行为不同于是出现结构体成员对不上、函数找不到声明的情况。先看内核是用哪个编译器编的# 内核构建时会记录编译器版本 cat /proc/version # 看当前默认 gcc 版本 gcc --version | head -1 # 看系统里装了哪些 gcc ls /usr/bin/gcc*如果/proc/version里显示的是gcc version 7.x而gcc --version是 9 或 10就要把编译用的编译器切回去。常见做法是用update-alternatives管理多版本或者直接在make时指定CC# 指定与内核匹配的编译器版本编译驱动 make CC/usr/bin/gcc-7 KDIR/lib/modules/$(uname -r)/buildCC指定编译器KDIR显式指向内核构建目录避免驱动 Makefile 自己猜路径猜错。如果系统里没有对应版本的 gcc需要从软件源补装。编完用modinfo看模块的vermagic是否和当前内核一致modinfo ./e1000e.ko | grep vermagic uname -r两边的内核版本串必须对得上后面带的内核配置标记比如SMP mod_unload也要一致否则加载时直接拒绝。这一步是很多人忽略的编完不验证vermagic等到insmod才报错又得回头重编。2.3 RTL8125 特有的 “unknown symbol” 与内核符号导出问题RTL8125 的驱动源码在较新版本里依赖一些内核网络子系统导出的符号在银河麒麟 V10 这种定制内核上部分符号可能没导出编译能过但加载时报insmod: ERROR: could not insert module r8125.ko: Unknown symbol in module用dmesg能看到具体缺哪个符号# 加载失败后立刻看内核日志定位缺失的符号名 sudo insmod r8125.ko dmesg | tail -20日志里会写Unknown symbol xxx (err -2)。err -2表示符号未找到。这种情况要么是内核配置里对应功能没开要么是驱动版本和内核版本不匹配。处理思路是先确认符号是否真的存在于当前内核# 在内核符号表里查这个符号是否存在 grep xxx /proc/kallsyms如果/proc/kallsyms里查不到说明内核根本没编进这个功能换驱动版本也没用得换内核或找厂商要适配版。如果查得到但驱动仍报未知符号多半是符号没有EXPORT_SYMBOL导出模块无法引用这种只能改驱动源码绕开该接口或者退回不依赖该符号的旧版驱动。RTL8125 的驱动分支比较多选版本时优先选和内核年代接近的那一支别盲目追最新。3. 模块加载成功但网卡不出现设备识别与 PCI 层面的排查编译过了、insmod也不报错lsmod里能看到e1000e或r8125但ip link里就是没有对应的eth或enp接口。这个阶段的问题已经不在编译而在设备识别、PCI 枚举和驱动绑定上。这一章按从硬件到驱动的顺序排查。3.1 先确认硬件是否被 PCI 总线识别lspci 看不到设备就别谈驱动驱动再对硬件没被枚举也是白搭。第一步永远是看 PCI 总线有没有认到这块网卡# 列出所有网络控制器确认厂商和设备 ID lspci -nn | grep -i -E ethernet|network正常应该看到类似Ethernet controller [0200]: Intel Corporation ... [8086:xxxx]或Realtek Semiconductor Co., Ltd. ... [10ec:8125]的行。如果lspci里压根没有网卡问题在硬件层网卡没插好、PCIe 插槽供电异常、BIOS 里禁用了板载网卡或者设备被pcinoacpi之类的启动参数挡掉了。这种情况驱动怎么装都没用先回硬件和 BIOS 排查。如果lspci能看到设备但后面跟的是Kernel driver in use: xxx为空或者显示的是别的驱动说明设备在但没绑到目标驱动上# 看某块网卡当前绑定的驱动和内核模块 lspci -k -s 总线地址-k会显示Kernel driver in use和Kernel modules两行。如果in use是空的说明没有驱动接管如果显示的是r8169而你装的是r8125那就是驱动冲突下一节细说。3.2 驱动绑定失败modprobe 成功但设备没被 probelsmod有模块、lspci有设备但接口不出现最常见的原因是驱动的 probe 函数执行失败。看内核日志是唯一可靠的手段# 清空环形缓冲区后重新加载模块抓取 probe 阶段的日志 sudo dmesg -C sudo modprobe -r e1000e 2/dev/null sudo modprobe e1000e dmesg | grep -i -E e1000e|eth日志里如果出现probe of xxxx failed with error -xx错误码就是线索。-19通常是ENODEV设备 ID 不在驱动支持列表里-12是ENOMEM内存分配失败-16是EBUSY设备已被别的驱动占用。针对设备 ID 不匹配的情况可以查驱动支持的 ID 列表# 查看模块支持的设备 ID modinfo e1000e | grep alias如果lspci里的设备 ID 不在 alias 列表里说明这个驱动版本不认识你的芯片型号需要换更新的驱动源码或者在驱动源码的 PCI ID 表里手动补一行。补 ID 是最后手段补之前先确认芯片型号确实属于该驱动家族别把不同代的芯片硬塞进去。3.3 接口命名规则变化网卡起来了但名字不是 eth0还有一种“假故障”网卡其实工作正常只是接口名不叫eth0。银河麒麟 V10 默认启用可预测网络接口命名接口可能叫enp3s0、eno1之类。很多人ifconfig看不到eth0就以为驱动没装上其实ip link里接口一直在。# 用 ip 命令看所有接口包括未启用的 ip link show # 只看有线网卡按类型过滤 ip -brief link show type etherip -brief输出更紧凑一眼能看出哪些接口是DOWN状态。如果接口在但状态是DOWNip link set 接口名 up启用即可。如果确实想让接口回到eth0这种传统命名可以改内核启动参数加net.ifnames0 biosdevname0但这会影响整机所有网卡命名生产环境改之前要评估别为了顺手把别的网卡配置搞乱。4. 网卡识别了却连不上链路、速率与驱动参数的坑接口出现在ip link里、状态也UP了但ping不通、拿不到 DHCP 地址或者链路时断时续。这一层的问题集中在物理链路协商、驱动参数和 2.5G 速率兼容性上RTL8125 尤其容易在这里翻车。4.1 链路显示 NO-CARRIER先分清是线的问题还是协商问题ip link里接口状态是NO-CARRIER意思是物理层没检测到对端信号。先排除最朴素的可能网线没插紧、网线是坏的、对端交换机端口没开。这些排除掉之后再看协商结果# 查看接口的链路检测和协商状态 sudo ethtool 接口名 # 查看支持的链路模式和当前协商模式 sudo ethtool 接口名 | grep -A 20 Supported link modesethtool输出里Link detected: no就是没链路。如果Supported link modes里有 2500baseT 但Advertised link modes里没有说明驱动没把 2.5G 模式广播出去对端只认千兆就可能协商不上。RTL8125 在部分交换机上需要手动指定速率# 强制指定速率和双工模式绕过自动协商 sudo ethtool -s 接口名 speed 1000 duplex full autoneg offspeed和duplex按对端能力填autoneg off关闭自动协商。强制模式是排查手段不是长期方案协商正常后应该改回autoneg on否则换根线或换个交换机端口又得手动改。如果强制千兆能通、自动协商不通基本可以锁定是 2.5G 协商兼容性问题考虑升级驱动或换交换机端口。4.2 RTL8125 的 2.5G 速率在千兆交换机上反复重连这是 RTL8125 最经典的坑网卡支持 2.5G插到只支持千兆的交换机上自动协商在 2.5G 和 1G 之间反复横跳表现为链路频繁 up/downdmesg里刷屏# 观察链路抖动连续看几秒 dmesg -w | grep -i -E link|r8125日志里会看到Link is Up和Link is Down交替出现。根因是驱动默认优先广播最高速率对端不支持时协商过程不稳定。处理办法有两个方向一是升级到较新的 r8125 驱动新版本对协商回退处理更稳二是在驱动加载参数里限制速率。r8125 支持通过模块参数控制# 加载时限制最高协商速率具体参数名以驱动源码为准常见为 speed_mode sudo modprobe r8125 speed_mode1参数含义要对照驱动源码里的module_param定义不同分支参数名可能不同别照抄。更稳妥的做法是写进/etc/modprobe.d/下的配置文件让每次开机自动生效# 写入模块参数配置开机自动应用 echo options r8125 speed_mode1 | sudo tee /etc/modprobe.d/r8125.conf # 重建 initramfs 让配置在早期启动阶段生效 sudo update-initramfs -uupdate-initramfs -u这一步很多人漏掉导致配置只在手动modprobe时生效重启后又回到老样子。改完重启验证dmesg里链路是否稳定。4.3 e1000e 的 “Detected Hardware Unit Hang” 与中断问题e1000e 在银河麒麟 V10 上偶发Detected Hardware Unit Hang表现为网络卡顿几秒后恢复dmesg里有e1000e 0000:00:1f.6: Detected Hardware Unit Hang这个报错根因通常是 TSOTCP Segmentation Offload或中断合并在高负载下和某些硬件版本配合不好。先确认是不是 offload 引起的# 临时关闭 TSO 和 GSO 验证 sudo ethtool -K 接口名 tso off gso off如果关闭后不再 hang说明问题在 offload。长期方案是写进网络配置或 udev 规则开机自动关闭。另一种常见处理是调整中断合并参数# 查看当前中断合并设置 sudo ethtool -c 接口名 # 关闭自适应中断合并固定合并参数 sudo ethtool -C 接口名 adaptive-rx off adaptive-tx off rx-usecs 0 tx-usecs 0adaptive-rx/tx off关掉自适应rx-usecs 0表示不延迟收包中断。这些参数对吞吐和 CPU 占用有影响调完要压测验证别在生产机上随手改。e1000e 的 hang 有时也和电源管理有关BIOS 里关掉 PCIe ASPM 能缓解一部分这属于硬件层手段放在最后试。5. 避坑与常见问题那些让我返工三次的细节这一章记录的是实际适配过程中反复踩到的坑每条都按现象、原因、解决三段写都是血泪经验照着避开能省不少时间。5.1 现象编好的 .ko 换台机器就加载失败原因模块的vermagic绑定了编译时的内核版本和配置两台机器内核小版本不同或者一台开了 SMP 一台没开模块就不兼容。很多人以为同是银河麒麟 V10 就能通用实际不同更新批次内核版本号差很多。解决每台目标机器上单独编译或者用modinfo xxx.ko | grep vermagic对比目标机uname -r不一致就重编。批量部署时把编译产物和内核版本绑定管理别混用。5.2 现象r8125 和系统自带 r8169 抢同一块网卡原因Realtek 的 r8169 是内核自带驱动会优先绑定部分 RTL8125 设备导致你装的 r8125 加载了但设备被 r8169 占着lspci -k里Kernel driver in use显示 r8169。解决把 r8169 加入黑名单阻止它自动加载# 黑名单屏蔽 r8169避免抢占 RTL8125 设备 echo blacklist r8169 | sudo tee /etc/modprobe.d/blacklist-r8169.conf # 重建 initramfs 后重启 sudo update-initramfs -u重启后确认lsmod | grep r8169为空lspci -k里驱动变成 r8125。注意黑名单只对自动加载生效如果 r8169 已经被编进内核built-in而非模块黑名单无效得靠内核启动参数或换内核解决。5.3 现象驱动装好后重启又失效原因手动insmod加载的模块重启后不会自动加载或者模块参数没写进配置文件。很多人装完当场能用第二天开机又回到没网的状态。解决把模块名写进/etc/modules或/etc/modules-load.d/下的配置文件参数写进/etc/modprobe.d/然后update-initramfs -u。三步缺一不可只写模块名不写参数参数会丢只写参数不重建 initramfs早期启动阶段加载的还是旧配置。5.4 现象dmesg 里 probe 报 -16 EBUSY原因设备已被其他驱动占用常见于 r8169 先绑定了设备或者上一次insmod的模块没卸干净。rmmod报Module in use也是同一类问题。解决先lsmod看谁占着lspci -k确认当前绑定驱动卸载占用驱动后再加载目标驱动。如果rmmod卸不掉用lsof或fuser查是否有进程持有网络接口停掉相关服务再卸。5.5 现象编译警告一堆以为没事加载后行为异常原因内核模块编译时的警告不能当耳旁风尤其是implicit declaration和类型不匹配的警告编出来的模块可能能加载但运行时行为不可预期比如收包丢包、中断处理异常。解决编译时加W1打开更多警告把警告当错误看# 打开额外警告编译暴露潜在问题 make W1 KDIR/lib/modules/$(uname -r)/build有警告先查清楚再加载别抱着“能跑就行”的心态网卡驱动跑在中断上下文里一个未定义行为可能就是随机丢包排查起来极其痛苦。6. 快速定位这类问题的顺序从 lspci 到 dmesg 的一条线网卡驱动问题看着杂其实排查有一条固定主线按顺序走能少绕很多路。我一般从硬件枚举开始一层层往上确认每层都有明确的判断依据不靠猜。第一步永远是lspci -nn | grep -i ethernet确认设备在总线上。设备不在后面全是空谈直接查硬件和 BIOS。设备在记下总线地址用lspci -k -s 地址看当前绑定的驱动这一步能立刻区分“没驱动”和“驱动绑错”两种情况。第二步看模块状态lsmod | grep -E e1000e|r8125|r8169确认目标模块是否加载、有没有冲突模块共存。模块没加载就modprobe加载失败看dmesg里的错误码-2查符号、-19查设备 ID、-16查占用错误码基本能定位到具体环节。第三步看接口ip -brief link show type ether列出所有有线接口和状态。接口不在回第二步查 probe接口在但DOWNip link set up接口UP但NO-CARRIER转ethtool查链路协商。第四步看链路和收发包ethtool 接口看Link detected和协商速率ethtool -S 接口看收发包计数和错误计数。错误计数持续增长说明物理层或驱动收包路径有问题结合dmesg里的 hang、reset 日志一起看。把这条线整理成一张对照表排查时对着填检查层命令正常表现异常时的下一步PCI 枚举lspci -nn | grep -i ethernet能看到网卡和厂商 ID查硬件、BIOS、插槽驱动绑定lspci -k -s 地址Kernel driver in use为目标驱动查黑名单、模块冲突模块加载lsmod | grep 驱动名模块在列表中看dmesg错误码接口存在ip -brief link show type ether有对应接口且状态符合预期查 probe 日志链路状态ethtool 接口Link detected: yes查网线、协商、强制速率收发包ethtool -S 接口错误计数不增长查 offload、中断、硬件最后一步是验证别只看“能 ping 通”就收工。用iperf3或dd走网络传大文件压几分钟同时dmesg -w盯着有没有 hang、reset、link down 的日志ethtool -S看错误计数有没有涨。很多问题在空闲时看不出来一上负载就暴露压测是唯一的后悔药。从那以后我每次在银河麒麟 V10 上装网卡驱动都强制走一遍“lspci 确认设备、lspci -k 确认绑定、dmesg 确认 probe、ethtool 确认链路、压测确认稳定”这五步一步不跳。这套流程看着笨但能把绝大多数“编译通过却不通”的问题挡在交付之前。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →