资讯动态

8188FU/8188FTV USB无线网卡驱动移植与wlan0排障实战

发布时间:2026/10/24 6:49:16 来源:尧图企业网站定制
简介面向在 Linux 与 Android 上调试 Realtek RTL8188FU、RTL8188FTV USB 无线网卡的开发者提供驱动源码、SDK 参考代码及配套文档。压缩包共 56 个文件、约 24.32MB以 28 个 PDF 说明文档、12 个 gz 源码/工具包为主并含 conf、txt、sh、diff 等配置、脚本与补丁文件便于按平台和版本检索。内容覆盖 Android 4.4 至 8.0 的参考实现、Linux 驱动编译安装说明以及 wpa_supplicant/hostapd、SoftAP、Station、桥接、功耗与调试日志等主题可帮助读者理解驱动移植、编译排错与功能验证流程。已有 9603 人学习下载适合需要补齐无线网卡驱动适配思路的中高级开发者参考。1. 一块 USB 无线网卡插上板子为什么平白无故少了个 wlan0板子上插进那颗 USB 无线网卡lsusb里明明躺着0bda:f179ifconfig -a却翻不出 wlan0dmesg也只留下孤零零一行new high-speed USB device。这不是玄学——8188FU、8188FTV 这类贴片模组的 USB WIFI 芯片主线的 rtl8xxxu 并没有覆盖到厂商驱动是以独立源码包形式分发的。这份资源就是那套驱动Linux 与 Android 两套构建入口都在能编出8188fu.ko接上 wpa_supplicant 就能扫 AP、连 SSID、开 softAP。它适合手上攒了一块模组、正给 ARM 板子或定制设备补无线能力的人也适合想完整读一遍 USB 无线驱动 vendor 实现的人。2. 项目定位与技术栈从 USB 枚举到 wiphy 注册的完整链路2.1 它在 Linux 无线子系统里站的位置用户态敲下iw dev wlan0 scan这条命令走 nl80211落到内核里就是 cfg80211 的 scan 回调。驱动要做的第一件事是向 cfg80211 注册一个 wiphy把支持的频段、速率集、加密套件、接口模式全部填进去注册完成/sys/class/ieee80211/下才会冒出phyX节点用户态才看得见这块网卡。8188FU/8188FTV 这套 vendor 驱动走的是 fullmac 路子管理帧的组装、扫描结果缓存、关联状态机都在驱动内部和固件里跑完对内核来说它像个黑匣子。所以整份源码里没有#include net/mac80211.h也没有ieee80211_ops取而代之的是os_dep/linux/ioctl_cfg80211.c里手写的一张cfg80211_ops表。这一点决定了后面读代码的姿势——你不能拿 mac80211 驱动的经验去套收发路径、MLME 状态全得在core/和hal/里自己找。对比一下主线内核的 rtl8xxxu它覆盖的是 8188CU、8188EU、8192CU 那一批8188F 系列不在名单内。板子换了芯片之后自带驱动认不出来只能上厂商包这也是很多人第一次踩坑的起点。层次组件关键点硬件8188FU / 8188FTVUSB 2.0 High Speed1T1R802.11n 150Mbps总线USB coreEP0 控制传输 bulk IN/OUT 数据 interrupt IN 事件驱动vendor driver自实现cfg80211_ops不走 mac80211用户态wpa_supplicant / hostapd通过 nl80211 下发扫描、关联、密钥2.2 源码目录四层结构改动点其实很集中拿到包先别急着make把目录翻一遍心里有张图后面改哪儿不慌。. ├── Makefile # 平台分叉点ARCH/CROSS_COMPILE/KSRC 都在这 ├── Kconfig ├── core/ # 协议与状态机与具体芯片无关的部分 │ ├── rtw_mlme.c # 关联/去关联状态 │ ├── rtw_mlme_ext.c # 管理帧收发、扫描流程 │ ├── rtw_cmd.c # 命令与固件消息队列 │ ├── rtw_xmit.c # 发送调度、优先级队列 │ ├── rtw_recv.c # 收包重排、分发到协议栈 │ ├── rtw_security.c # WEP/TKIP/AES 加解密 │ └── rtw_efuse.c # efuse 读校准数据 ├── hal/ │ ├── rtl8188f/ # 芯片相关寄存器、PHY、RF、电源序列 │ ├── phydm/ # 数字与射频校准的公共库 │ └── hal_dm.h ├── os_dep/ │ ├── linux/ │ │ ├── os_intfs.c # module_init/module_exit注册 usb_driver │ │ ├── usb_ops_linux.c # 端点读写、urb 管理 │ │ ├── ioctl_cfg80211.c # cfg80211_ops 表 wiphy 填充 │ │ ├── netdev_ops.c # ndo_open/ndo_start_xmit │ │ └── xmit_linux.c # skb 到 urb 的衔接 │ └── android/ ├── include/ │ ├── autoconf.h # 几乎所有功能开关都在这一份里 │ └── drv_types.h └── platform/core/是逻辑hal/rtl8188f/是硬件方言os_dep/是操作系统适配include/autoconf.h是总闸。要加型号、要裁体积、要改调试输出八成落在最后两份文件上。我第一次读的时候在core/里绕了两天其实真正决定能不能跑起来的是hal/rtl8188f/rtl8188f_halinit.c里的初始化顺序和os_dep/linux/usb_ops_linux.c里的端点映射。2.3 两套构建入口Makefile 与 Android.mk 的分工Linux 侧走的是标准外部模块那套顶层 Makefile 选平台然后make -C $(KSRC) M$(PWD) modules内核的 Kbuild 接手真正编译。Android 侧稍麻烦老一点的做法是塞进内核树里用obj-m 8188fu.o加一行再用整个内核的交叉工具链编新一点的做法是走Android.mk用BUILD_EXTERNAL_KERNEL_MODULE直接产出.ko放进 vendor 分区。两条路的产物都是同一个.ko区别只在编译时的内核头文件来源。Android 的 kernel header 必须和设备实际内核完全对得上vermagic差一个字符都加载不了。我一般会直接从设备上cat /proc/version再去找同版本源码而不是拍脑袋用某个通用内核。3. 编译与加载把 .ko 塞进内核的完整实操3.1 编译前的三样东西缺一样都白干第一样是内核源码或至少Module.symvers齐全的头文件目录路径要指向一个已经make modules_prepare过的树否则编到一半报Module.symvers is missing。第二样是交叉工具链版本尽量和设备内核编译时用的一致GCC 大版本跨了容易在-Werror上翻车。第三样是内核配置基线至少这几项要是y或m# 在目标内核的 .config 目录下核对缺项就补上重编内核 grep -E CONFIG_USB|CONFIG_USB_SUPPORT|CONFIG_CFG80211|CONFIG_MODULES .config grep -E CONFIG_CFG80211_WEXT|CONFIG_WIRELESS .configCONFIG_CFG80211是硬门槛没有它驱动链接时就会缺wiphy_new之类的符号。CONFIG_CFG80211_WEXT决定iwconfig那套老接口还在不在用iw的话可以不开。CONFIG_MODULES要是不开那只能把驱动编进内核insmod这条路直接断掉。这三项我每次换板子都会先 grep 一遍,省得编完再回头折腾。3.2 Makefile 里必须改的四个变量顶层 Makefile 前面一大段是几十个CONFIG_PLATFORM_xxx开关属于历史包袱不用全看找到自己平台对应的那一段改就行。以 ARM 板子为例# 顶层 Makefile 片段先关掉默认的 x86 平台再打开自己的 CONFIG_PLATFORM_I386_PC n CONFIG_PLATFORM_ARM_RPI y ifeq ($(CONFIG_PLATFORM_ARM_RPI), y) # 小端平台必须打这个宏否则 PHY 寄存器读写会得到一堆反过来的值 EXTRA_CFLAGS -DCONFIG_LITTLE_ENDIAN ARCH : arm CROSS_COMPILE : arm-linux-gnueabihf- KSRC : /opt/kernel/linux-4.19 MODULE_NAME : 8188fu endifARCH和CROSS_COMPILE决定用哪套工具链KSRC是外部模块编译的根MODULE_NAME决定产物文件名。CONFIG_LITTLE_ENDIAN这个宏特别容易被忽略尤其是从大端平台抄配置过来的人编出来能加载、能起接口就是扫不到任何 AP——因为读回来的校准数据和寄存器值全是字节序反的。如果不想改源码里的 Makefile也可以在命令行覆盖make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- \ KSRC/opt/kernel/linux-4.19 \ -j$(nproc)这条命令跑完当前目录会出8188fu.ko。-j后面给核数编译量不大四核机器大概一两分钟。失败时先看最后二十行通常是某个内核 API 签名对不上属于版本适配问题不是配置问题。3.3 内核版本适配那些改了签名又没打招呼的接口vendor 驱动发布时对应某个内核版本往新内核上搬最常见的三类不兼容是这样的老代码用init_timer(timer)5.0 之后换成timer_setup(timer, cb, 0)老代码的cfg80211_scan_request里wiphy和ifidx是两个字段新版本合成了wdevndo_select_queue的参数从三个变成了四个多了sb_dev。这类改动不难但很啰嗦属于纯体力活。我自己的处理顺序是先只改编译报错让它过再跑加载看dmesg里有没有 WARN最后才做功能验证。上来就一边改 API 一边调功能出了问题分不清是适配错了还是配置错了血泪经验。/* 老写法在内核 5.x 上会直接报 implicit declaration */ init_timer(pmlmeext-scan_timer); pmlmeext-scan_timer.function _scan_timeout_handler; /* 新写法回调签名固定为 void (*)(struct timer_list *) */ timer_setup(pmlmeext-scan_timer, _scan_timeout_handler, 0);这段改动的逻辑很直白就是把函数指针赋值换成注册时绑定回调的第一个参数从unsigned long变成struct timer_list *原来靠data字段传的adapter指针现在得用from_timer()反查。改完记得全局搜一遍init_timer漏一个就白编。3.4 加载、起接口、连上第一个 AP# 1. 加载模块先别急着重启直接 insmod 看反馈 sudo insmod 8188fu.ko sudo dmesg | tail -n 20 # 2. 确认接口出现注意可能是 wlan0 也可能是 wlan1取决于系统已有几块网卡 ip -br link show # 3. 拉起接口并扫描 sudo ip link set wlan0 up sudo iw dev wlan0 scan | grep -E SSID|signal | head -n 20dmesg里正常应该能看到 USB 端点信息、efuse 读取、MAC 地址、以及最后的register netdev之类。如果只有 USB 枚举没有后续说明 probe 半路返回了错误往下看-ENODEV、-ENOMEM这些返回值能定位到哪一步。扫到 AP 之后连网配置文件大概长这样# /etc/wpa_supplicant.conf ctrl_interface/var/run/wpa_supplicant update_config1 network{ ssidlab-2g psk替换成你自己的口令 key_mgmtWPA-PSK protoRSN pairwiseCCMP }ctrl_interface决定wpa_cli能不能连上做调试时建议开着能交互式看扫描结果和关联状态。protoRSN对应 WPA2如果你手上 AP 只开 WPA 就改成WPApairwise写TKIP。配置文件写错最常见的表现是4-Way Handshake failed跟驱动没关系是密钥或加密套件对不上。# -B 后台运行-D 指定驱动后端-i 指定接口 sudo wpa_supplicant -B -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf sudo dhclient wlan0 ping -c 4 192.168.1.1-D nl80211是让 wpa_supplicant 走 cfg80211 接口如果系统里这个后端没编进去会报Failed to initialize driver interface那就退回-D wext前提是内核开了CONFIG_CFG80211_WEXT。3.5 Android 侧从 .ko 到开机自动加载Android 上多出来的麻烦主要是三件模块放哪儿、谁来加载、权限够不够。存放位置通常是/vendor/lib/modules/Android 10 之后基本统一到这里。加载有两种方式一种是init.rc里显式insmod另一种是写进modules.load由 init 按顺序批量加载# /vendor/lib/modules/modules.load # 每行一个模块名init 会按这个顺序 insmod 8188fu.komodules.load的好处是顺序可控坏处是加载失败时日志被淹没在一堆模块里。我一般开发阶段先用init.rc显式写insmod /vendor/lib/modules/8188fu.ko跑通了再挪进modules.load。权限这块.ko文件要打上vendor_file标签否则 SELinux 会拦下insmod日志里是avc: denied { read }看着像文件不存在其实是被拒了。另外如果内核开了CONFIG_MODULE_SIG_FORCE.ko必须用同一套私钥签名不签会报Required key not available。这两条在定制设备上非常常见属于不看日志永远猜不到的类型。4. 核心代码拆解一次 probe 到 wiphy 注册的完整链路4.1 入口usb_driver 与 id_table驱动的起点不是module_init是那张设备 ID 表。USB 核心枚举到设备后拿idVendor/idProduct去和所有已注册的usb_driver表比对命中才调probe。/* os_dep/linux/usb_intf.c 附近这是驱动的匹配入口 */ static struct usb_device_id rtw_usb_id_tbl[] { #ifdef CONFIG_RTL8188F /* VID/PID 一组一组列同一个芯片贴不同模组会有好多组 */ {USB_DEVICE(0x0bda, 0xF179), .driver_info RTL8188F}, #endif { /* 结束标记删了它 USB 核心会越过表尾读内存 */ } }; MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl); static struct usb_driver rtl8188fu_driver { .name rtl8188fu, .id_table rtw_usb_id_tbl, .probe rtw_drv_probe, .disconnect rtw_drv_disconnect, /* 部分模组需要在 reset_resume 里重新走一遍初始化 */ .reset_resume rtw_reset_resume, };driver_info是给驱动自己用的标记驱动内部靠它区分具体是哪颗芯片因为 8188FU 和 8188FTV 共享大部分代码路径只在射频和接口配置上有细微差别。MODULE_DEVICE_TABLE这个宏不是给人看的是给depmod生成别名用的热插拔时才认得出。删掉它insmod之后手动插拔可能就不工作了。4.2 probe从 usb_interface 到 adapter 私有结构/* 简化后的 probe 主干真实代码里还有一堆错误分支 */ static int rtw_drv_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct dvobj_priv *dvobj; struct adapter *padapter; int ret; /* 1. 一块网卡可能导出多个 interfaceif0 做控制if1 才是数据面。 * 先把它们归到同一个 dvobj 里后续复用同一份总线资源 */ if (intf-cur_altsetting-desc.bInterfaceNumber ! 0) return -ENODEV; dvobj usb_dvobj_init(intf); if (!dvobj) return -ENODEV; /* 2. if1 才是真正要注册 net_device 的那一个 */ padapter rtw_usb_if1_init(dvobj, intf, id); if (!padapter) { usb_dvobj_deinit(intf); return -ENODEV; } /* 3. 绑回 interfacedisconnect 时靠它取回 adapter */ usb_set_intfdata(intf, padapter); /* 4. 硬件初始化上电序列、固件下载、efuse 读校准 */ if (rtw_hal_init(padapter) _FAIL) goto error; return 0; error: rtw_usb_if1_deinit(padapter); return -ENODEV; }bInterfaceNumber ! 0这一句是很多插上没反应的根因。有些模组把控制口放在 if0有些放在 if1还有的只导出单接口。判断条件写死成 0 之后换一种模组就直接返回-ENODEVdmesg里只留一行灰色的错误非常难查。我遇到这种会先lsusb -v把bInterfaceNumber全抄下来再决定这个判断要不要放宽。rtw_hal_init是真正的重活给芯片上电、跑电源序列、下载固件、读 efuse 拿 MAC 地址和发射功率校准值。这一步失败通常不会是代码问题而是硬件没接好或者电源不够尤其是 USB 供电的板子模组峰值电流上去了就掉。4.3 发送一个 skb 从协议栈到 bulk OUT上层调ndo_start_xmit进到rtw_xmit_entry做优先级映射、填 TX 描述符最后交给usb_write_port。/* os_dep/linux/xmit_linux.cskb 进入驱动后的第一站 */ int rtw_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev) { struct adapter *padapter rtw_netdev_priv(pnetdev); struct xmit_priv *pxmitpriv padapter-xmitpriv; s32 ret; /* 超过硬件描述符能带的长度就直接丢别指望下层分片 */ if (skb-len pxmitpriv-max_xmit_extbuf_size) goto drop; /* 打上优先级标记后面映射到 4 个硬件队列之一 */ skb-priority rtw_classify8021d(skb); ret rtw_hal_xmit(padapter, pxmitpriv-xmit_frame_priv, skb); if (ret ! _SUCCESS) goto drop; return NETDEV_TX_OK; drop: dev_kfree_skb_any(skb); return NETDEV_TX_OK; }rtw_classify8021d把上层给的 802.1D 优先级映射到 03 的硬件队列VO/VI/BE/BK 四档。不做 QoS 的话这段可以简化但别删删了队列索引会越界。往下到usb_write_port就是标准的 URB 三件套usb_alloc_urb、usb_fill_bulk_urb、usb_submit_urb。真正的坑在完成回调里——驱动要从 urb 的context拿回自己的pxmitbuf再把它还回空闲队列。这里如果引用计数没配平跑一段时间就会看到队列空、发包全超时现象特别像驱动挂了其实只是 buffer 泄漏干净了。4.4 接收从 bulk IN 到 netif_rx接收是驱动主动轮询的初始化时提交若干个 bulk IN URB每个完成回调里重新提交形成一条常驻的收包链。/* usb_ops_linux.c单个接收 URB 的完成回调简化版 */ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs) { struct recv_buf *precvbuf (struct recv_buf *)purb-context; struct adapter *padapter precvbuf-adapter; switch (purb-status) { case 0: /* 正常收完把长度填进 context交给上层解析 */ precvbuf-purb purb; recvbuf2recvframe(padapter, precvbuf); break; case -ESHUTDOWN: /* 设备已经拔了直接返回不要再重投 URB */ return; default: break; } /* 重新提交保持接收链不断。这里失败要退避否则会打爆日志 */ usb_submit_urb(purb, GFP_ATOMIC); }purb-status的判断顺序很重要-ESHUTDOWN必须排在重投之前否则拔卡一瞬间会疯狂重投日志刷屏到看不见别的。GFP_ATOMIC是因为回调运行在中断上下文不能睡眠。recvbuf2recvframe之后会做 802.11 头解析、去重、解密然后netif_rx交给协议栈。这套流程是 vendor 驱动自建的和 mac80211 的ieee80211_rx完全两回事读的时候别混。4.5 cfg80211 注册wiphy 是怎么被填满的/* ioctl_cfg80211.c这张表就是驱动对用户态暴露的全部能力 */ static struct cfg80211_ops rtw_cfg80211_ops { .change_virtual_intf cfg80211_rtw_change_iface, .add_key cfg80211_rtw_add_key, .get_key cfg80211_rtw_get_key, .del_key cfg80211_rtw_del_key, .scan cfg80211_rtw_scan, .connect cfg80211_rtw_connect, .disconnect cfg80211_rtw_disconnect, .join_ibss cfg80211_rtw_join_ibss, .get_station cfg80211_rtw_get_station, .set_channel cfg80211_rtw_set_channel, /* 不写的回调用户态调用时直接返回 -EOPNOTSUPP */ };表里没列出来的回调用户态调用会拿到-EOPNOTSUPP。这就是为什么有些驱动iw list看着正常iw dev wlan0 connect却失败——connect回调压根没实现只能走 wpa_supplicant 的 nl80211 协商路径。注册之前还要填wiphy-bands、wiphy-interface_modes、wiphy-cipher_suites这三样决定了用户态看见的频段列表、支持的接口类型STA/AP/P2P和加密套件。填漏一个对应的功能就是不可用而不是报错查起来相当费劲。5. 排查手册模块加载成功却扫不到 AP 的五种现场5.1 insmod 成功dmesg 里却没有 probe 日志现象lsmod能看到8188fudmesg里除了insmod相关的一行没有任何和网卡有关的输出ip link里也没有新接口。原因ID 表没匹配上。要么 PID 不在表里贴牌模组改过 ROM要么bInterfaceNumber判断把设备挡在了外面要么 USB 核心根本没把设备枚举到驱动上——后者常见于接口被别的驱动先占住了。解决先lsusb -v -d 0bda:把实际的idProduct和所有bInterfaceNumber打出来和rtw_usb_id_tbl对一遍再lsusb -t看设备挂在哪个驱动下如果是usb-storage之类说明这个模组是复合设备需要先解绑再绑。5.2 有 wlan0iw list 报 nl80211 not found现象接口起来了ip link能看到wlan0但iw list直接报nl80211 not foundiw dev也报错。原因内核没开CONFIG_CFG80211或者开成了模块但没加载也可能是cfg80211加载了但wiphy注册失败驱动这边回了错误却没打印。解决ls /sys/class/ieee80211/看有没有phyX节点没有就是注册失败回去看wiphy_register的返回值。另外zcat /proc/config.gz | grep CFG80211确认配置别只看.config文件有些发行版会把配置塞进/boot。5.3 Android 上 insmod 直接 unknown symbol现象insmod: failed to load 8188fu.ko: Unknown symbol in moduledmesg里能看到具体缺哪个符号。原因两件事之一。内核版本和.ko编译时用的头文件对不上vermagic不匹配或者内核里对应功能的配置没开导出符号不存在。解决modinfo 8188fu.ko | grep vermagic和uname -r对一下不一致就重新用正确内核编。符号缺失的话cat /proc/kallsyms | grep 符号名确认到底有没有导出没有就只能改内核配置重编没别的路。5.4 能连上但吞吐只有几 Mbps 还丢包现象关联成功ping通但 iperf 跑下来只有几 Mbps偶尔丢包iw dev wlan0 station dump里速率一直是低档。原因多数是射频校准数据没读到或者字节序配错了。efuse 里的发射功率校准值读成乱码芯片就会用默认的低功率发射CONFIG_LITTLE_ENDIAN没开的话PHY 寄存器读回来全是反的速率协商自然上不去。解决dmesg里搜 efuse 相关输出确认有没有EEPROM/EFUSE读取成功的日志再确认 Makefile 里的字节序宏和板子一致。实在不行用iw dev wlan0 set bitrates legacy-2.4 54手动锁速率看能不能跑满能跑满就说明是速率自适应算法的问题而不是硬件。5.5 休眠唤醒后网卡消失rfkill 显示 blocked现象系统挂起再唤醒wlan0没了rfkill list里对应项是Soft blocked: yes。原因部分平台在 resume 时没有正确走reset_resumeUSB 设备重新枚举了但驱动没重新绑定或者 rfkill 状态被电源管理逻辑重置了。解决usb_driver结构体里把.reset_resume挂上让唤醒后走一遍轻量化的重新初始化再rfkill unblock all验证是不是纯状态问题。如果 unblock 之后立刻又变 blocked那是平台侧的 GPIO 或 ACPI 在管得从设备树或电源管理配置里改。6. 二次开发改 ID 表、裁体积以及怎么验证没改坏6.1 给贴牌模组补一个 PID改动只有两行最常见的一次改造是拿到一块不在 ID 表里的模组。改法极简/* 在 rtw_usb_id_tbl 里补一行driver_info 按实际芯片填 */ #ifdef CONFIG_RTL8188F {USB_DEVICE(0x0bda, 0xF179), .driver_info RTL8188F}, {USB_DEVICE(0x1234, 0x5678), .driver_info RTL8188F}, /* 贴牌模组 */ #endif注意driver_info要和芯片真正对应。填错了不会报错只是射频参数按另一颗芯片走表现出来就是能连、速率低、或者距离一远就断。改完先lsusb -v确认bInterfaceNumber再确认模组的bNumEndpoints和驱动假设的端点数量对得上——有些模组少了 interrupt IN驱动初始化到那一步会返回失败得把对应的活儿改成轮询。6.2 裁剪把 .ko 从几 MB 压到几百 KBinclude/autoconf.h里几乎每个CONFIG_xxx都是一个功能开关关掉就少编译一批文件。我一般会先关这几个CONFIG_AP_MODE不做热点、CONFIG_P2P不做直连、CONFIG_DEBUG去掉大量 printk、CONFIG_MP_INCLUDED去掉产测模式、CONFIG_BTCOEX_SUPPORT没有蓝牙共存需求。/* include/autoconf.h注释掉即关闭 */ //#define CONFIG_AP_MODE //#define CONFIG_P2P //#define CONFIG_DEBUG //#define CONFIG_MP_INCLUDED关CONFIG_DEBUG效果最明显代码体积能掉三分之一但调试期间别关出事了两眼一抹黑。我的习惯是出正式包前才关而且关完一定要把 5.4 那条吞吐问题重新跑一遍——有些日志本身带副作用关掉之后时序变了反而暴露新问题。这就是我说的后悔药留一份开 debug 的.ko在手里出问题能立刻换回去对比。6.3 改完怎么确认没改坏跑三条iw list看频段和接口模式对不对iw dev wlan0 scan看能不能扫到至少三个 APiperf3 -c跑一分钟看吞吐曲线平不平。三条都过了再谈功能够不够。表里列一下我在不同改动后重点看的东西改动重点验证失败时的典型现象加 PIDprobe 日志完整、MAC 地址非全 0接口出现但扫不到 AP关 AP_MODEiw list的 interface modes 不含 APhostapd 启动报 not supported关 DEBUG吞吐、丢包率与开启时一致时序变化导致偶发丢包改字节序宏efuse 校准值合理、速率能上高档能连但速率锁在 1Mbps有一次我图省事改完 ID 表直接出了固件没跑扫描验证结果现场十几台设备全是能连路由器、连不上特定型号 AP。回头查了半天是那颗模组的射频参数需要单独在hal/rtl8188f/里覆盖一份默认值在那台 AP 的信道上功率不够。从那以后我每次动 ID 表和 autoconf都强制走一遍扫描 跑流 换信道三连不管改动看起来多小。希望帮到你。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑