银河麒麟V10网卡驱动编译实战:e1000e与rtl8125完整指南
简介面向在银河麒麟V10上配置网络环境的系统工程师与运维人员这份源码包提供了e1000e与RTL8125两款网卡驱动的可编译版本。针对国产系统内核与硬件适配中的常见障碍资源在原始代码基础上删除了重复定义并调整了函数参数以匹配麒麟V10的编译环境可直接缩短驱动安装与排错周期。包内含56个文件、约483KB以C源代码和头文件为主并附Makefile、README及驱动加载辅助脚本目录同时保留e1000e-3.8.4与RTL8125Linux两套源码结构便于对照修改和二次编译。已有2719人学习下载适合需要部署Intel或Realtek网卡驱动的银河麒麟用户参考也适合Linux驱动开发者研究国产系统下的内核兼容性。 预装的银河麒麟V10桌面系统接上网线后右下角网络图标一直转圈打开网络设置连有线连接的入口都看不到。lspci里明明能看到网卡型号可就是没有对应驱动在跑。这种场景在这两年的国产化项目里太常见了——银河麒麟V10的内核版本相对保守对新出的板载网卡支持不全尤其是Intel的e1000e系列和Realtek的rtl8125 2.5G网卡很多情况下都要自己重新编译驱动。这篇文章把我实际编译e1000e和rtl8125驱动的过程完整走一遍包括编译环境准备、源码获取、踩坑记录和DKMS持久化适合正在做国产化替代、需要在麒麟系统上补硬件驱动的朋友直接参考。1. 为什么好好的网卡在银河麒麟V10上消失了1.1 先弄清楚网卡为什么没驱动Linux系统里网卡驱动本质上是一个内核模块系统启动时通过udev识别硬件然后按硬件ID去匹配内核里现有的模块。银河麒麟V10虽然是国产操作系统但底层还是Linux内核只是它的内核版本和内核配置相对走保守路线。这里说的保守有两个含义。第一是内核版本不算新比如很多银河麒麟V10桌面版用的是4.19.x或5.4.x内核板载网卡芯片如果出的比较晚老内核源码树里根本没有对应的驱动代码自然就不认识这块网卡。第二是内核config裁剪即便内核源码里包含某个驱动的代码如果编译内核时没把这个模块选中最终装到用户机器上的内核镜像同样没有这个驱动。拿e1000e来说它是Intel千兆以太网卡的通用驱动支持82571到I219等一大票芯片。可问题在于老内核自带的e1000e版本太旧面对较新的I219-V这类网卡接口时经常出现驱动加载成功但link不起来或者干脆连PCI ID都对不上。rtl8125就更典型了它是Realtek的2.5G有线网卡芯片很多新主板都板载这个但Linux主线内核一直到5.x中后期才逐步把这块支持进r8168/r8125驱动体系里在老版本的银河麒麟V10上基本就是裸奔状态。1.2 用这三条命令确认问题定位遇到网卡不工作先别急着下载驱动编译花一分钟把问题定位清楚。我一般按这个顺序查lspci -nnk | grep -i ethernet ip link dmesg | grep -i eth第一条命令看系统是否识别到了网卡PCI设备以及当前有没有驱动绑定在上面。如果输出里显示的是Ethernet controller: Intel Corporation Ethernet Connection (7) I219-V但后面没有Kernel driver in use: e1000e说明设备被识别了但没驱动接管。第二条命令看当前网络接口列表正常情况会显示eth0或enp开头的接口驱动没加载的话这里通常只有lo回环接口。第三条命令查内核日志看系统启动时有没有报网卡相关的错误比如e1000e: probe of 0000:00:1f.6 failed with error -5这类信息。三种情况可以快速判断设备都没出现可能是BIOS里被禁用设备出现但没驱动绑定说明内核模块缺失或加载失败设备、驱动、接口都有但link不上再看网线、交换机和对端设备。注意lspci输出里网卡设备名后的括号数字是PCI ID比如8086:15bc后面查驱动支持情况时会用到。2. 编译前先把环境对齐内核头文件是分水岭2.1 银河麒麟V10的两种体系要分清银河麒麟V10分桌面版和服务器版桌面版基于Debian体系用apt管理软件包服务器版比如银河麒麟高级服务器操作系统V10基于CentOS/RHEL体系用yum或dnf。这个差异直接决定了安装编译工具链的命令。我一开始在桌面版上用yum命令安装死活找不到软件包后来一查才发现版本搞混了所以第一步先看系统信息cat /etc/os-release桌面版输出里能看到IDkylin和VERSIONV10服务器版会有ID:kylin但包管理工具完全不同。另外还可以通过which apt或which yum快速判断。2.2 安装工具链和内核头文件编译内核模块最少需要三样东西编译器gcc、make工具、以及和当前运行内核完全匹配的内核头文件。银河麒麟V10的软件源里都有直接装桌面版Debian系sudo apt update sudo apt install -y build-essential dkms linux-headers-$(uname -r)服务器版RHEL系sudo yum install -y gcc make dkms kernel-devel-$(uname -r) kernel-headers这里有个细节值得强调linux-headers或kernel-devel的版本号必须和uname -r输出完全一致。我见过不少人编译失败最后发现原因是系统里装了多个内核版本头文件装的是旧版本的而当前跑的是新内核编译时引用到的/lib/modules/$(uname -r)/build根本不存在。如果是这样先把系统重启到想用的内核版本或者用yum install kernel-devel-$(uname -r)指定版本号安装一次装齐。2.3 编译前必须做的一次自检装完工具链后别急着解压驱动源码先执行这条验证命令ls /lib/modules/$(uname -r)/build正常情况下这个目录是指向内核头文件的符号链接能列出Makefile和相关子目录。如果没有这个目录或者ls报错那编译任何模块都会失败而且报错都很诡异。最常见的报错是./include/linux/compiler.h: No such file or directory看到这个第一反应就该去查头文件装没装对。再确认一下gcc版本gcc --version银河麒麟V10桌面版一般自带gcc 7.x或9.x服务器版可能是8.x或9.x。gcc版本太高或太低偶尔也会引发编译问题但先不用纠结等真遇到报错再处理。把环境自检这一步做完后面编译驱动基本就是走流程的事。3. e1000e编译实测Intel官方源码的完整流程3.1 从Intel官网找对源码版本e1000e驱动源码在Intel官网下载中心能找到搜索e1000e linux driver即可当前主流版本是3.8.x。下载后是一个以源码包形式提供的tar.gz文件。这里有个经验尽量下载最新版因为Intel会持续往里面加新网卡芯片的PCI ID。我在银河麒麟V10上适配I219-V时最初用的是3.4.2版本编译和加载都没问题但网卡就是link不起来查了半天发现旧版本驱动对I219-V的某些物理层配置有问题换了最新的3.8.4之后一次就通了。如果你不确定自己网卡芯片属于哪个驱动系列可以查Intel官网的驱动支持矩阵或者直接看lspci输出的设备ID。e1000e覆盖的主要是PCI ID以8086:15开头的一批千兆芯片像8086:15b8I219-LM、8086:15bcI219-V都在支持列表里。3.2 make和make install实际操作源码包下载后按这个流程操作tar -xzf e1000e-3.8.4.tar.gz cd e1000e-3.8.4/src make编译过程中如果环境准备充分一般不会有报错。它编译出来的模块文件叫e1000e.ko。接下来安装sudo make install这个命令会把编译好的模块放到/lib/modules/$(uname -r)/updates/drivers/net/ethernet/intel/e1000e/目录下然后执行depmod更新模块依赖关系。注意make install不会自动加载模块需要手动处理。有个容易混淆的点系统里原本可能已经有一个e1000e模块在老内核的/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/intel/e1000e/下make install之后新模块会优先于旧模块被加载因为updates目录的优先级更高。这样设计的好处是即使你编译的版本有问题至少还能通过modprobe参数回退不至于把系统搞死。3.3 加载模块并验证结果sudo modprobe e1000e dmesg | tail -20看到类似e1000e: Intel(R) PRO/1000 Network Driver - 3.8.4-NAPI和e1000e 0000:00:1f.6: The NVM checksum is not valid这类日志说明驱动已经开始和网卡交互。如果没有报错再用ip link看接口状态此时应该能看到eth0或enp0s31f6这样的网络接口出现了。如果需要固定接口名称可以在/etc/default/grub里追加net.ifnames0参数或者用udev规则重命名。我自己习惯保留系统默认命名因为改接口名可能会影响其他依赖eth0的服务配置尤其在国产化项目里很多上层应用写死了接口名动这个要谨慎。4. rtl8125编译实测从autorun.sh翻车到手动编译成功4.1 Realtek官方驱动的目录结构rtl8125的Linux驱动在Realtek官网下载中心能找到文件名通常是rtl8125-x.x.x.tar.gz版本号各家渠道略有差异。解压后目录结构很简单tar -xzf rtl8125-9.011.00.tar.gz cd rtl8125-9.011.00里面最显眼的是一个autorun.sh脚本旁边是src目录和Makefile。Realtek官方推荐直接跑./autorun.sh它会自动执行清理、编译、安装、加载一整套流程。看着确实省事但我在银河麒麟V10上用它翻过车下面详细说。4.2 autorun.sh为什么容易翻车autorun.sh有几个问题。第一它内部会先执行make clean然后再make如果内核头文件配置有问题报错信息被它自动吞掉一部分用户只看到一句Build failed根本不知道哪一步出了问题。第二它对内核版本比较敏感在老内核上也许能用但在新内核上编译报错时不会给你任何选择版本或打补丁的机会。第三它最后会自动modprobe r8125一旦模块加载失败系统网络配置可能处于半初始化状态排查起来反而更麻烦。更稳妥的做法是绕开autorun.sh手动进src目录分步编译。这样每一步的报错都看得清定位问题快得多。4.3 手动编译的正确流程cd src make clean make如果编译顺利会出现r8125.ko。但rtl8125这个驱动在较新内核上编译报错是常态。我在5.4内核上遇到过报错error: implicit declaration of function pci_alloc_irq_vectors之类这通常是驱动源码版本太老调用了新内核已经调整的API。遇到这类情况去Realtek官网下最新版驱动基本都能解决Realtek这些年在Linux驱动维护上已经比前几年好很多了。编译通过后安装并加载sudo make install sudo modprobe r8125验证方式和e1000e类似lsmod | grep r8125 ip link ethtool eth0rtl8125是2.5G网卡加载成功后通过ethtool eth0能看到Speed: 2500Mb/s但前提是网线、交换机端口、对端设备都得支持2.5G。如果对端只有千兆口它会自动协商到1000Mb/s这属于正常现象别误以为驱动有问题。5. 让驱动升级内核后也不掉线DKMS注册与自动重建5.1 为什么要做DKMS手动编译安装的驱动有个隐患银河麒麟V10只要进行内核升级旧内核被替换后/lib/modules/新版本/build目录里的模块不会自动带过去网卡驱动在新内核下就没了。系统重启后网卡再次消失又得重新解压源码、编译、安装非常折腾。DKMSDynamic Kernel Module Support就是解决这个问题的标准方案。它把驱动源码注册到系统里每次内核变更后自动重新编译并安装对应模块。对运维来说这意味着以后无论系统怎么打补丁、升内核驱动都能自动跟上不用人工干预。5.2 dkms.conf长什么样DKMS注册驱动要求源码目录里必须有一个dkms.conf配置文件。很多官方驱动包包括rtl8125已经自带了但e1000e的Intel源码包不一定有。如果没有手动创建一个放在源码根目录PACKAGE_NAMEe1000e PACKAGE_VERSION3.8.4 BUILT_MODULE_NAME[0]e1000e DEST_MODULE_LOCATION[0]/updates MAKE[0]make -C src CLEANmake -C src clean AUTOINSTALLyes注意DEST_MODULE_LOCATION的取值有讲究。对于由make install直接安装的模块一般放在/updates下即可如果你的系统有特定模块目录规范也可以改成/kernel/drivers/net/ethernet/intel/e1000e。rtl8125自带的dkms.conf里通常已经写好了这些配置直接使用就行。5.3 注册、构建、安装三步走以e1000e为例源码放在/usr/src/e1000e-3.8.4DKMS要求路径结构是/usr/src/包名-版本号然后执行sudo cp -r e1000e-3.8.4 /usr/src/ sudo dkms add -m e1000e -v 3.8.4 sudo dkms build -m e1000e -v 3.8.4 sudo dkms install -m e1000e -v 3.8.4中间如果build失败用sudo dkms status能看到错误状态然后查/var/lib/dkms/e1000e/3.8.4/build/make.log里的详细报错。安装完成后dkms status会显示e1000e/3.8.4: installed。rtl8125同理只是模块名和版本号按实际来sudo cp -r rtl8125-9.011.00 /usr/src/ sudo dkms add -m r8125 -v 9.011.00 sudo dkms build -m r8125 -v 9.011.00 sudo dkms install -m r8125 -v 9.011.00之后每次内核升级DKMS触发自动重编后观察一下状态即可。这一步做完整个驱动适配才算真正收尾不用每次更新系统都提心吊胆。6. 编译中的高频报错与个人排错心得6.1 Secure Boot导致的模块拒绝加载银河麒麟V10在很多预装设备上默认开启了UEFI的Secure Boot。Secure Boot开启时内核只会加载有合法签名的模块。我们自己编译的.ko文件没有签名modprobe时会报错module verification failed: signature not found或Required key not available。检查是否开启mokutil --sb-state输出SecureBoot enabled说明确实开着。解决方案有两个一是去BIOS里关掉Secure Boot这对大部分内网项目最简单直接二是给模块签名需要自己生成密钥、用mokutil --import导入MOK、重启后用mokutil --enable-validation确认流程比较繁琐。个人建议如果不是安全等级要求特别高的环境直接关掉省事但做之前要确认项目合规要求。6.2 编译报错高频问题对照表我在实际编译过程中遇到过的问题和对应解法整理成表格供参考报错信息根因解决方案./include/linux/compiler.h: No such file内核头文件未安装安装linux-headers或kernel-devel/lib/modules/xxx/build: No such file头文件版本与当前内核不匹配安装与uname -r一致的头文件包implicit declaration of function驱动源码过旧内核API已更新下载新版驱动源码Cannot use CONFIG_CC_STACKPROTECTOR_STRONGgcc版本与内核编译选项不兼容装回匹配的gcc版本或调整内核configmodule verification failedSecure Boot阻止加载关闭Secure Boot或签名模块Unknown symbol类报错模块依赖的其他符号未加载先加载依赖模块或检查module order6.3 排错实践中的几条经验先把系统软件源配置好。银河麒麟V10的软件源有时候需要手动指向本地源或镜像源尤其是内网环境。源没配好装个linux-headers都装不上后面全白干。第二编译之前把uname -r记到纸上后面所有依赖这个版本的步骤都以它为准别凭记忆。第三网卡驱动这种底层模块修改前先备份原厂系统镜像或至少备份/lib/modules目录一旦编译出来的模块有问题至少能恢复。还有一个容易被忽略的细节如果机器里同时装了两块网卡一块是Intel一块是Realtek先把不用的那块在BIOS里禁用排除干扰因素。我遇到过排查半天发现驱动没问题是两块网卡的PCI分配把接口序号搞乱了。做国产化系统适配很多时候其实不是技术不行而是环境没对齐。只要内核头文件版本正确、工具链完整、驱动源码版本匹配银河麒麟V10上编译网卡驱动和普通Ubuntu、CentOS几乎没有区别。希望这套流程能帮你少走点弯路一次把网卡点亮。本文还有配套的精品资源点击获取