资讯动态

RK3399 USB以太网驱动编译与多网口配置实战

发布时间:2026/10/27 21:56:58 来源:尧图企业网站定制
板子上能用的原生网口只有一个串口占了调试通道剩下的 USB 口还空着——这是我接手这个 RK3399 项目时看到的第一眼硬件布局。需求很朴素同一台设备要同时接一路内网采集、一路外网回传还得给调试电脑留个口一个千兆原生口显然不够。翻了一圈方案加交换机、换带多网口的核心板、上 USB 以太网适配器三条路里最省钱、改动最小、也最容易回退的就是最后一条插一个 USB 以太网网卡把内核里 usbnet 那一套驱动跑起来。听起来像插上就能用实际动手才发现RK3399 这种嵌入式平台上USB 以太网编译和安装这件事卡人的地方从来不是插拔而是内核配置没开、模块版本对不上、固件没放对位置、开机不自动加载这几步。这篇就把我从零到跑通、再到稳定压测的完整过程摊开写包括选型时踩的坑、只编单个模块的省时做法、以及在板子上做双网口路由的那点经验适合正在折腾 RK3399 或类似 ARM64 平台、需要扩展网络接口的同行参考。1. 先把需求捋清楚为什么非得给板子挂个 USB 以太网1.1 板载原生网口不够用的三个真实场景很多教程一上来就讲编译跳过了为什么结果读者照着敲完命令驱动加载了却不知道自己要拿它干什么后面配 IP、配路由全抓瞎。我先说说我这边的三个场景基本能覆盖大部分人的需求。第一种是多网段隔离。设备一头接现场的内网采集设备网段是 192.168.1.x另一头要把数据回传到上层服务器网段是 10.10.x.x两个网段物理隔离、不能互通。只有一个网口的话要么加一台交换机再做 VLAN要么就得来回改配置,前者增加成本后者根本没法同时在线。第二种是调试口独立。开发阶段我习惯用 SSH 连板子但一旦我在原生网口上改 IP、改路由、重启网络服务SSH 必断人就被踢出去了只能跑去接串口。多一个 USB 网口专门留给调试链路改另一个口的配置时心里踏实得多这个习惯我保持了很多年救过不少次现场。第三种是功能验证与备用链路。有些项目要求主链路故障时能自动切到备用通道USB 网卡插上去就是现成的第二张网卡配个路由 metric 就能做主备切换验证成本极低。而且 USB 网卡坏了大不了换一个几十块钱的事比返修主板划算太多。把这三个场景想明白后面所有的配置选择才有依据——你要的是能通还是能扛住长时间跑决定了你是随手 insmod 一下还是老老实实做开机自动加载和稳定性测试。1.2 芯片选型从 AX88772 到 RTL8153 的取舍USB 以太网适配器市面上五花八门外壳长得都差不多里面的主控芯片差别很大。买之前一定看商品详情页有没有写芯片型号没写的直接跳过那种大概率是便宜货内核里驱动支持得零零碎碎。我手上这几类都用过整理成一张表芯片方案接口速率内核配置项是否需固件实际体验AX88772 系列百兆CONFIG_USB_NET_AX8817X否老而稳几乎不需要折腾适合只要通网的场景AX88179 系列千兆CONFIG_USB_NET_AX88179_178A否千兆里兼容性最好的之一USB3.0 下能跑起来RTL8152/8153 系列百兆/千兆CONFIG_USB_RTL8152部分型号需要性能不错但固件缺失时会加载失败坑最多CDC ECM / NCM 类视设备而定CONFIG_USB_NET_CDCETHER / CDC_NCM否免驱类通用性好性能一般选型上我的建议很直接如果只是想给板子多加一个网口优先选 AX88179 或 AX88772内核里配置项单一、不依赖外部固件、加载即用省心。如果你追求千兆吞吐并且能接受折腾RTL8153 系列性能确实更好但要提前把固件文件准备好否则 modprobe 之后 dmesg 里会出现固件加载失败的报错网卡根本出不来。还有一个容易忽略的点USB 口的速度等级决定上限。RK3399 平台上通常有 USB2.0 和 USB3.0 接口千兆网卡插在 USB2.0 口上理论带宽 480Mbps实际跑个 280~330Mbps 就到顶了网卡再好也没用。插之前先确认你插的是哪个口别回头测出来只有两百多兆就怀疑驱动有问题。1.3 内核支持和能用之间隔着好几道坎新手最容易有的一个误解是内核源码里明明有 r8152.c 这个文件为什么板子上插了网卡没反应。原因很现实——源码里有不等于编译进去了。厂商给的默认 defconfig 为了控制镜像体积通常只保留了最基础的一批驱动USB 网络这一块经常是关的或者是编成模块但从来没往文件系统里装过。所以完整链路其实是四步内核配置里把对应选项打开、编译出 .ko 文件、把 .ko 放到板子文件系统的正确目录、让系统在启动时自动加载它。任何一步断了表现都是插上网卡没反应而这四种没反应的排查方向完全不同。后面我会按这四步分开讲每一步都给出确认方法这样你卡住的时候知道自己在哪一段。顺便提一句有些厂商的 BSP 内核会把 usbnet 编进内核built-in但具体某个网卡驱动编成模块。这种情况下你只要补那一个 .ko 就行不用重编整个内核能省下大量时间。所以在动手之前先摸清楚现状比闷头编译重要得多。2. 编译前的准备把内核源码和工具链理顺2.1 先确认板子上跑的内核和你手上的源码是不是同一份这一步我吃过亏必须放在最前面说。模块和内核之间有一条硬约束vermagic 必须完全一致包括内核版本号、SMP 是否开启、抢占模式、模块版本校验这些信息。版本号差一个字符insmod 就会甩给你一句 invalid module format然后你盯着源码看半天也看不出问题。确认方法很简单板子上执行uname -r cat /proc/version把输出记下来比如4.4.189或者5.10.110然后到源码根目录看 Makefile 前几行的VERSION、PATCHLEVEL、SUBLEVEL是不是对得上。对不上就说明你手上的源码不是板子上跑的那份要么去问厂商要对应版本的 BSP 包要么就接受编出来的模块装不上这个结果。还有一种情况更隐蔽版本号一样但配置文件不一样。比如板子上跑的内核开了CONFIG_PREEMPT你手上这份源码的 .config 没开编出来的模块 vermagic 里会多一个preempt或者少一个照样装不上。所以最稳妥的做法是直接从板子上把当前配置抠出来# 板子上执行前提是内核开了 IKCONFIG zcat /proc/config.gz board_defconfig如果/proc/config.gz不存在那就只能找厂商要编译这份内核时用的 defconfig 文件。拿到之后放到源码的arch/arm64/configs/目录下后面配置内核时直接用它做基线能最大程度保证一致性。2.2 交叉编译工具链的选择与验证RK3399 是 ARM64 架构编译要在 x86 主机上做需要 aarch64 的交叉工具链。工具链的选择上不用太纠结主流的两条路一是用厂商 BSP 包里自带的预编译工具链路径一般在prebuilts/gcc/linux-x86/aarch64/下面二是用系统包管理器装一个比如 Ubuntu 上的gcc-aarch64-linux-gnu。我个人的偏好是优先用厂商自带的理由很实际内核里有些汇编代码对编译器版本比较敏感换个版本可能出现奇怪的编译错误或者运行时行为差异厂商既然验证过就别给自己找麻烦。当然如果你只是编个 USB 网卡模块用系统工具链一般也没问题。装好之后先验证一下aarch64-linux-gnu-gcc --version能打印出版本信息就说明 PATH 里能找到。如果用的是厂商工具链通常需要手动加路径export PATH$PWD/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH export CROSS_COMPILEaarch64-linux-gnu- export ARCHarm64这三个环境变量建议写进一个envsetup.sh脚本里每次开新终端 source 一下省得反复敲。ARCHarm64这一条千万别漏漏了的话 make 会按主机架构去编译报一堆莫名其妙的错误。2.3 一次干净的基线编译别省这一步在改配置之前我强烈建议先做一次原样编译确认工具链、源码、配置这套组合本身是能跑通的。这步看着多余其实是在排除变量如果基线都编不过你改完配置编不过就分不清是配置改错了还是环境本来就有问题。命令大致是这样具体目录名按你的源码结构来cd kernel make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- your_defconfig make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- -j$(nproc) Image dtbs第一次编译时间会比较长四核八线程的机器上大概二三十分钟看源码规模和机器性能。编完检查一下arch/arm64/boot/Image有没有生成有就说明基线没问题。如果这一步就报错常见原因是缺依赖包。Ubuntu 上一般需要装bison、flex、libssl-dev、libncurses5-dev、bc这几个缺哪个报错信息里都会写照着装就行。还有个小坑有些老版本内核配新版 gcc 会报-Werror相关的警告直接中断编译这种可以在 make 后面加KCFLAGS-Wno-error临时绕过但更推荐换个匹配的工具链版本。3. 内核配置把 USB 以太网驱动真正打开3.1 menuconfig 里的关键路径与选项含义配置入口用make menuconfig图形界面里按这个路径找Device Drivers→Network device support→USB Network Adapters。进去之后你会看到一长串选项第一次看容易懵我把几个关键的说清楚配置项含义是否必选CONFIG_USB_USBNETusbnet 框架本体所有 USB 网卡驱动的底座必选CONFIG_MII媒体独立接口库usbnet 依赖它必选通常默认已开CONFIG_USB_NET_AX8817XAX88772 系列百兆方案按需CONFIG_USB_NET_AX88179_178AAX88179 系列千兆方案按需CONFIG_USB_RTL8152RTL8152/8153 系列按需CONFIG_USB_NET_CDCETHERCDC ECM 免驱方案按需CONFIG_USB_NET_CDC_NCMCDC NCM 免驱方案按需CONFIG_USB_NET_SMSC75XXSMSC 75xx 系列按需CONFIG_USB_USBNET是底座没有它上面那些具体驱动一个都编不出来这个依赖关系在新手眼里经常被忽略——明明勾了 AX88179编出来没有 .ko就是因为它爹没开。实际选的时候不用全开按你手上的网卡芯片勾对应的就行多开了只会让镜像变大、编译变慢。我一般会顺手把CONFIG_USB_NET_CDCETHER和CONFIG_USB_NET_CDC_NCM也打开编成模块理由很朴素免驱类设备太常见了同事随手拿个网卡过来测试、或者临时要接个带网口的扩展坞有这两个模块在手能省很多事。3.2 编成模块还是直接编进内核这个问题每次都会被问到我的答案取决于你的使用场景编成模块m好处是不用重新烧写内核镜像把 .ko 拷到板子上 modprobe 就能用出问题也好回退。缺点是文件系统里得留位置放 .ko而且开机自动加载要多配一步。开发调试阶段我几乎全部选这个。编进内核y好处是开机就有不用管模块加载适合量产固件。缺点是每次改动都要重新烧内核调试周期长而且会让内核镜像变大几十到上百 KB。还有一个折中做法值得推荐usbnet 框架和 MII 编进内核y具体网卡驱动编成模块m。这样底座常驻插不同网卡只需要加载对应的那一个 .ko既灵活又不至于每次都动内核。这个组合我在好几个项目里都用了很顺手。配置改完记得保存menuconfig 里选Save默认写到.config。保险起见再确认一下grep -E USB_USBNET|USB_NET_AX88179|USB_RTL8152|CONFIG_MII .config输出里能看到y或m就说明写进去了。有时候图形界面里勾了但保存失败就是权限或者磁盘问题用 grep 确认一遍最踏实。3.3 只编模块的省时办法改完配置如果只编模块完全不用重新编整个内核这一步能省下大量时间。正确姿势是先做一次 prepare然后指定目录编译make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- modules_prepare make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- Mdrivers/net/usb modulesmodules_prepare的作用是准备好编译模块所需的头文件和脚本只需要跑一次。M指定只编drivers/net/usb这个子目录几十秒就能出结果。有个坑必须提前说用modules_prepare编出来的模块有可能因为缺少Module.symvers而在加载时报 unknown symbol。原因是modules_prepare不会生成完整的内核符号表。解决办法是老老实实跑一次完整的内核编译不用烧写把Module.symvers生成出来然后再编模块。这也是为什么我前面强调先做一次基线编译——它顺手就把符号表准备好了。编译完成后产物在drivers/net/usb/目录下ls -lh drivers/net/usb/*.ko正常情况下能看到usbnet.ko、mii.ko如果 MII 编成模块的话、ax88179_178a.ko或者r8152.ko。用modinfo检查一下版本信息对不对modinfo drivers/net/usb/ax88179_178a.ko | head -20重点看vermagic那一行和你板子上uname -r的输出比对一下一致才能往下走。3.4 RTL8153 的固件准备这是最容易被忽略的一步如果你选的是 RTL8152/8153 系列还有一个额外的活要干准备固件文件。部分型号在初始化时需要从/lib/firmware/加载固件缺了就会加载失败。固件文件通常是这几个名字rtl_nic/rtl8153a-2.fw、rtl8153a-3.fw、rtl8153a-4.fw、rtl8153b-2.fw等等具体需要哪个取决于芯片的具体版本。这些文件一般在源码树的firmware/目录或者厂商的 BSP 包里能找到也可以从上游的 linux-firmware 仓库获取。放的位置是# 板子上的目标路径 /lib/firmware/rtl_nic/目录不存在就自己建。放好之后加载驱动用 dmesg 确认固件加载成功。如果看到类似 Direct firmware load failed 的报错八成就是文件名或者路径不对仔细核对一下内核源码里r8152.c中写死的固件名别猜。4. 安装到板子从拷贝到开机自动加载4.1 传输通道怎么选以及为什么别用 U 盘把 .ko 传到板子上常用三条路网络scp、串口通过终端软件的传输功能、U 盘。我的建议是能用网络就别用别的原因很实际U 盘插拔容易碰到其他设备而且有些文件系统挂载之后权限位会乱串口传输速度慢还容易丢包。前提当然是你板子现在的网络是通的。如果原生网口已经配好了scp 一条命令搞定scp drivers/net/usb/*.ko root192.168.1.100:/tmp/如果板子还没网那就先接串口或者用 TF 卡拷过去这个阶段忍一忍就行。另外提醒一句拷贝之前先在板子上建个临时目录别一股脑往/root里扔后面清理的时候容易漏。4.2 目录放置与 depmod模块依赖怎么处理模块的正确落点是/lib/modules/$(uname -r)/kernel/drivers/net/usb/注意版本号是从板子上uname -r动态取的别手敲。放好之后跑一次depmoddepmod -a $(uname -r)这一步的作用是扫描所有模块把依赖关系写进modules.dep和modules.alias。为什么要做这一步因为ax88179_178a.ko依赖usbnet.kousbnet.ko又依赖mii.ko你直接 insmod 具体驱动会报 unknown symbol 之类的错。跑完 depmod 之后用modprobe加载它会自动把依赖链按顺序拉起来省事。验证依赖关系有没有写进去modinfo -F depends ax88179_178a正常应该输出usbnet,mii之类的内容。如果是空的说明 depmod 没扫到检查一下文件是不是放对目录了、文件名后缀对不对。注意depmod跑完之后如果你又拷了新模块进去必须重新跑一次否则新模块的依赖关系和别名不会更新。这个坑我见过不止一次表现为模块明明在目录里modprobe 却说找不到。4.3 加载、卸载与开机自动加载手动加载先验证一遍modprobe ax88179_178a然后dmesg | tail -30看输出。成功的标志是能看到类似usb 1-1.2: new high-speed USB device、ax88179_178a 1-1.2:1.0 eth1: register ax88179_178a这样的日志并且ip link里能看到新接口。卸载用modprobe -r ax88179_178a注意如果接口还处于 up 状态卸载会失败先ip link set eth1 down。开机自动加载有两种方式我推荐第一种# 方式一modules-load.d干净利落 echo ax88179_178a /etc/modules-load.d/usbnet.conf # 方式二写入 /etc/modules部分老系统用这个 echo ax88179_178a /etc/modulesmodules-load.d是 systemd 体系下的标准做法配置文件里一行一个模块名开机由 systemd-modules-load 服务统一处理不依赖其他脚本的执行顺序。比往rc.local里塞 insmod 靠谱得多——rc.local 在有些发行版里默认是关的你改完以为生效了重启一看白干。还有一种情况要考虑热插拔。如果你的使用方式是板子先开机网卡后插那就不能只靠开机加载。要么让驱动常驻编进内核或者开机就 modprobe要么配 udev 规则触发加载。实际上 usbnet 驱动加载之后是常驻的检测到新设备会自动绑定所以只要驱动在内存里热插拔没问题。我一般就是开机直接 modprobe插拔随意。4.4 接口命名不叫 eth1 怎么办现在不少发行版启用了 predictable network interface names新插的网卡可能不叫eth1而是一串类似enx00e04c123456的名字中间那段是 MAC 地址。这不是出错是命名规则变了。如果脚本里写死了eth1就会一路报错。两个选择一是改脚本用新名字二是把命名规则关掉# 关闭 predictable names用传统的 ethX 命名 ln -s /dev/null /etc/systemd/network/99-default.link或者在/etc/udev/rules.d/下加一条规则按 MAC 地址固定命名SUBSYSTEMnet, ACTIONadd, ATTR{address}00:e0:4c:12:34:56, NAMEeth1我偏向第二种因为固定了名字之后不管系统怎么升级、怎么改命名策略这块网卡永远是eth1脚本不用动。缺点是换一块网卡就得改规则但生产环境里一般不会随便换。5. 验证、配置与性能实测5.1 dmesg 和 ethtool 要看哪几个关键信息驱动加载完第一件事是确认它真的被识别成了什么样的设备dmesg | grep -i -E usb|eth ethtool -i eth1ethtool -i的输出里重点看三个字段driver是驱动名得和你加载的模块对得上version是驱动版本bus-info是挂在哪个 USB 总线上形如1-1.2:1.0。这个 bus-info 后面调电源管理的时候要用。再看链路状态ethtool eth1输出里Speed显示 1000Mb/s 还是 100Mb/s、Duplex是全双工还是半双工、Link detected是不是 yes一目了然。如果显示 100Mb/s先别急着怀疑驱动八成是网线的问题——老的五类线跑千兆会协商降速换根超五类或者六类线再试。还有一种情况是Link detected: no但网卡确实插着对端交换机也是好的。这种多半是 USB 供电不足尤其在小体积的 HUB 上。表现是网卡枚举出来了但 PHY 初始化不完整。换个带独立供电的 HUB 试试或者直接插板子上的 USB3.0 口。5.2 IP 配置与双网口路由接口通了之后配 IP。先用 iproute2 那套命令比老的 ifconfig 更清晰ip addr add 192.168.10.2/24 dev eth1 ip link set eth1 up ip route add 192.168.10.0/24 dev eth1如果要配成 DHCP 客户端udhcpc -i eth1 # 或者 dhclient eth1看系统里装的是哪个双网口的核心问题是默认路由走谁。两个网口都配了网关的话系统里会出现两条 default 路由谁先加谁的 metric 小流量就走谁很容易出现内网能通、外网不通或者反过来。正确做法是只给一个口配默认网关另一个口只加网段路由# 主链路走默认网关 ip route add default via 192.168.1.1 dev eth0 metric 100 # 副链路只走自己的网段不抢默认路由 ip route add 192.168.10.0/24 dev eth1 metric 200如果你需要主备切换主链路断开自动切副链路可以在同一条 default 上配不同 metricip route add default via 192.168.1.1 dev eth0 metric 100 ip route add default via 192.168.10.1 dev eth1 metric 200metric 小的优先主链路 down 掉之后内核会自动切到 metric 大的那条。这套机制很简单但很可靠我用了很多次比装一堆路由协议软件轻量得多。5.3 带宽实测与长跑稳定性性能这块不测心里没底。用 iperf3 最方便PC 端起服务端板子上跑客户端# PC 端 iperf3 -s # 板子端-t 60 表示跑 60 秒 iperf3 -c 192.168.1.50 -t 60参考数据AX88179 插在 RK3399 的 USB3.0 口上千兆链路实测单向大约 850~940Mbps双向同时跑会掉到各自四五百兆。同样的网卡插在 USB2.0 口上顶天 300Mbps 出头。RTL8153 在 USB3.0 下能跑到 900Mbps 上下差距不大但小包性能通常略好一点。长跑测试我一般跑 30 分钟以上观察两个指标一是吞吐有没有随时间下降二是dmesg里有没有出现NETDEV WATCHDOG或者 USB reset 相关的日志。出现 USB reset 基本可以确定是供电或者线材问题驱动本身很少是这个原因。再补充一个容易被忽略的参数关闭 USB 自动挂起。默认情况下内核为了省电会让空闲的 USB 设备进入低功耗状态网卡频繁进出这个状态时可能丢包或者断连。关闭方法echo -1 /sys/bus/usb/devices/1-1.2/power/autosuspend路径里的1-1.2就是前面ethtool -i看到的 bus-info。要持久化的话写成 udev 规则或者开机脚本别指望手动 echo 一次就完事。6. 踩坑实录与问题速查6.1 常见问题速查表下面这些是我这几年攒下来的基本覆盖了 USB 以太网在 RK3399 上出问题的绝大多数情况现象大概率原因排查动作插上网卡毫无反应dmesg 无任何日志USB 口没供电或设备没枚举换口、换线、看lsusb有无新设备有 USB 枚举日志但没有 net 接口注册对应网卡驱动没加载lsmod看驱动在不在modprobe手动加载modprobe 报 module not found.ko 没放到/lib/modules/$(uname -r)/或没跑 depmod检查目录、重跑depmod -ainsmod 报 invalid module formatvermagic 不匹配对比modinfo的 vermagic 和uname -rmodprobe 报 unknown symbol依赖模块没加载或 Module.symvers 缺失先加载 usbnet/mii重编模块驱动加载了但接口没有 IP也拿不到 DHCP链路没起来或对端没开 DHCPethtool看 Link detectedip link看状态RTL8153 加载失败日志提示固件固件文件缺失或路径不对放到/lib/firmware/rtl_nic/千兆网卡只协商到 100Mbps网线质量或对端口速率换六类线检查交换机端口配置跑一段时间后断连dmesg 有 USB reset供电不足或 USB 自动挂起换带供电 HUB关闭 autosuspend重启后网卡不见了没配开机自动加载写/etc/modules-load.d/配置6.2 几条文档里不会写的经验第一条先lsusb再谈驱动。很多人插上网卡第一步就去 modprobe加载失败就开始怀疑内核配置。正确的顺序是先lsusb看设备有没有被 USB 子系统枚举出来能不能看到厂商 ID 和产品 ID。看不到的话问题在硬件层——供电、线材、接口跟驱动一点关系都没有。这一步能省掉大量无效排查。第二条别迷信免驱。商家标榜的免驱通常是指 Windows 下免驱Linux 下能不能用完全看内核有没有对应的驱动。买之前查一下芯片型号在内核源码drivers/net/usb/目录下有没有对应的 .c 文件比看商品详情页靠谱一百倍。第三条模块文件别只拷一个。依赖链上的usbnet.ko、mii.ko都要一起拷少一个就加载失败。我见过有人只拷了ax88179_178a.ko然后对着 unknown symbol usbnet_generic_cdc_bind 这种报错查了一下午。第四条改完内核配置一定要 grep 确认。menuconfig 图形界面偶尔会出现勾了没保存的情况尤其是用 SSH 连过去跑的时候网络一抖。保存之后grep一下.config几秒钟的事能避免一次白编译。第五条量产固件里把驱动编进内核更省心。调试阶段用模块方便量产时建议把 usbnet 和相关驱动都改成y省掉模块加载和文件系统依赖减少一个可能出问题的环节。这个切换点我一般放在功能验证完成、开始做稳定性测试之前。6.3 关于固件体积的一点取舍最后聊个实际项目中会遇到的权衡。RK3399 平台的固件通常放在 eMMC 上空间不算紧张但把整个drivers/net/usb目录下所有驱动全编进去加起来也就几百 KB对固件体积影响很小。所以我个人的做法是量产固件里把常见的几类 USB 网卡驱动全编进内核包括 AX88772、AX88179、RTL8152、CDC ECM、CDC NCM。理由是现场环境不可控客户或者施工方随手拿来的网卡什么芯片都有可能驱动不全就得远程指导人家换网卡沟通成本远高于几百 KB 的存储开销。这个决定我在两个项目里做过事后都被证明是对的——现场救急的时候多一个驱动就少一次返工。反过来如果你的固件要刷到几万台设备上、升级带宽有限那就精简到只留项目指定的那一款芯片其余全关。这时候驱动选择就得跟着采购清单走BOM 里写的是什么芯片内核里就只留什么驱动别留余地避免现场插错网卡反而引发一堆兼容性问题的排查。这套流程从选型到编译、从部署到压测我在三块不同批次的板子上都走过一遍每次卡住的地方都不太一样但排查路径是通用的。真正让我少走弯路的不是记住了多少条命令而是养成了先确认现状、再动手改的习惯——先uname -r看版本先lsusb看设备先lsmod看模块把现状摸清楚剩下的基本就是按图索骥。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑