RTL8733BU USB WiFi模块在MC6810平台上的Linux驱动适配实践 简介这份资源是一套面向嵌入式开发者的 USB WiFi 模块驱动源码包型号为 RTL8733BU兼容 RTL8733、RTL8731 芯片并已适配 MC6810 平台及 Linux 4.9.138 内核解决开发者在特定硬件与内核版本下获取稳定无线驱动的问题。压缩包共 1098 个文件大小约 11.06MB核心内容以 C 语言源码与头文件为主221 个 .c、485 个 .h同时包含编译脚本、配置命令、模块文件等辅助材料适合用来理解驱动移植、编译和加载流程。文件命名中的版本号与日期可供判断驱动的新旧与更新节奏。已有 678 人学习下载。对正在基于 Linux 4.9.138 进行嵌入式 WiFi 功能开发或需要参考 RTL8733BU 驱动移植思路的工程师来说这份源码提供了一套完整的代码结构和模块化目录便于直接开展驱动适配、内核编译与无线功能调试。1. USB WiFi 模块 RTL8733BU 在 MC6810 平台这份适配包能省你多少事做嵌入式开发的经常会遇到这种状况主板画好了、系统能起来USB WiFi 模组插上去却没反应dmesg 里只有一段 USB 枚举信息之后就没有下文。手头这块 MC6810 板子跑 Linux 4.9.138 内核WiFi 模块用的是 RTL8733BU它和 RTL8733、RTL8731 系列共用同一套驱动源码。这套资料的价值在于它已经按 4.9.138 这个内核版本做过逐项手工适配包含驱动源码、固件布局、NVRAM 配置和编译脚本能把 USB 枚举、固件加载、双频扫描这条路一次走通。适合板卡 BSP 开发、系统集成验证以及换了主控平台后需要把老 WiFi 模组重新救回来的场景。2. 内核配置与驱动编译先让 USB 枚举不再玄学2.1 为什么 RTL8733BU 不能靠内核自带驱动直接工作Linux 4.9.138 内核里其实已经有 rtlwifi 目录mac80211 框架和 cfg80211 也都是现成的但 RTL8733BU、RTL8733、RTL8731 这一批较新的 USB 芯片默认不在主线支持列表里。内核源码树里只有 rtl8xxxu 这类覆盖老 USB 网卡的驱动新芯片要靠厂商驱动的 out-of-tree 编译方式加进来。这也是刚接触的人最容易翻车的地方以为内核开了某个通用 USB WiFi 驱动选项就行实际芯片完全不识别。out-of-tree 编译的意思是把厂商驱动源码放在内核源码目录之外通过内核提供的 Kbuild 机制编出 .ko再用 insmod 或拷贝进 rootfs 自动加载。这么做的最大好处是不用改动内核源码本身平台 SDK 换内核小版本时驱动目录可以独立维护坏处是vermagic 校验和内核版本强相关4.9.138 环境编出来的 .ko 拿到 4.9.172 的板子上基本不能用。适配包里通常会有 README 说明它基于哪个驱动基线。MC6810 的 BSP 用 4.9.138 内核编译这个驱动时要注意内核源码里的scripts/mod/mk_elfconfig和 modpost 工具版本必须和编内核时用的是同一套否则后面 modinfo 查 vermagic 会对不上。2.2 内核侧需要提前确认的配置项在介入驱动之前先把内核基础打开。MC6810 的 BSP 通常自带能启动的 defconfig但“能启动”和“能把 WiFi 跑起来”之间还隔着几个配置开关。下面这几个必须确认是y而不是m否则模块加载顺序会乱嵌入式场景下不建议把无线协议栈编成模块再依赖自动加载。配置项菜单路径本场景建议CONFIG_USByDevice Drivers - USB support必须否则芯片无法枚举CONFIG_NET_RADIOyNetworking - Wireless必须无线子系统入口CONFIG_CFG80211yNetworking - Wireless必须提供无线配置管理CONFIG_MAC80211yNetworking - Wireless必须驱动依赖的协议栈CONFIG_WIRELESS_EXTyNetworking - Wireless建议兼容旧式无线工具CONFIG_CRYPTO_AESCryptographic API建议确认WPA2 握手需要 AES按 4.9.138 的 menuconfig 路径操作一遍cd /opt/kernel-4.9.138 make ARCHarm menuconfig进入 Networking support - Wireless把 cfg80211 和 mac80211 都编进内核。脚本化构建的环境可以直接查 .configgrep -E CONFIG_USB|CONFIG_CFG80211|CONFIG_MAC80211 /opt/kernel-4.9.138/.config这行命令的含义是快速核对三个关键配置。如果输出是m说明还是模块需要改成y重新编译内核。我做项目时习惯先把内核编好并固化再单独编 WiFi 驱动这样排查问题时只需要盯住驱动目录不用每次连带内核一起重来。2.3 用适配包里的 Makefile 交叉编译驱动适配包顶层结构按芯片厂商标准目录展开包含 include、hal、os_dep、core、platform 这些子目录顶层有 Makefile。它支持自动探测内核目录也支持手动指定。在 MC6810 上我习惯手动指定把配置写进环境变量export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- export KERNELDIR/opt/kernel-4.9.138 cd /path/to/rtl8733bu_driver make clean make -j8简单说明这几个环境变量的作用ARCH 告诉 Kbuild 目标体系结构是 ARMCROSS_COMPILE 指定用哪套交叉工具链KERNELDIR 指向 4.9.138 的内核源码目录。如果 BSP 用的是 64 位工具链把前缀换成对应 aarch64 前缀即可不要混用 32 位和 64 位工具链编 arm 内核模块。编完后确认模块信息file 8733bu.ko modinfo 8733bu.ko | head -20驱动器的主模块名常见是 8733bu.ko不同适配包命名可能不一样以顶层 Makefile 的obj-m输出为准。modinfo 里看 vermagic应该和内核的 vermagic 一致包括 SMP、preempt、ARM 的 p2v8 这些后缀缺一项都说明编译环境不匹配。模块编出来之后放到 rootfsmkdir -p /target/rootfs/lib/modules/4.9.138/ cp 8733bu.ko /target/rootfs/lib/modules/4.9.138/ cd /target/rootfs find . -name *.ko -exec arm-linux-gnueabihf-strip --strip-debug {} \;strip 这一步的目的是减小镜像体积。注意只剥离 debug 段不要用--strip-all把符号表全部剥掉否则模块加载时无法解析依赖关系。目标板空间紧张时在开发机上做 strip 更合适不要在已经部署的板子上执行。2.4 模块加载顺序与可调参数驱动自动加载时要保证 usbcore、mac80211、cfg80211 都先于 8733bu 就位。用 modprobe 时系统会通过 modules.dep 处理依赖但直接 insmod 的场景下顺序写错会报 “Unknown symbol”。适配包一般附带加载脚本典型内容如下#!/bin/sh insmod /lib/modules/4.9.138/cfg80211.ko insmod /lib/modules/4.9.138/mac80211.ko insmod /lib/modules/4.9.138/8733bu.ko rtw_drv_log_level1rtw_drv_log_level是驱动日志级别参数0 表示只输出错误1 带警告2 起包含调试信息。第一次调试建议开到 1 或 2稳定后改回 0。日志级别开太高在低端 CPU 平台上连续打日志反而会拖累网络吞吐。如果驱动在加载时提示参数不存在说明该适配包用的驱动基线里没有开启CONFIG_DRV_LOG_LEVEL需要在 Makefile 里打开后重新编译。3. 固件与 NVRAM信号差异和认证失败都藏在这些文件里3.1 芯片固件加载机制与文件放置RTL8733BU 这类 USB WiFi 芯片内部只有 Boot ROM完整的 802.11 协议处理固件是主机侧通过 USB 批量传输写进芯片内存的。驱动枚举成功后会从/lib/firmware/rtlwifi/下读取对应 bin 文件一次性下载到芯片。固件版本和驱动编译时的预期要匹配否则 dmesg 里会给出固件版本不匹配的警告功能上表现为连不上 AP 或扫描列表为空。驱动适配包里 firmware 目录一般包含这几个文件rtl8733bu 的 WiFi 固件、蓝牙固件、NVRAM 配置。放到目标板的正确做法是mkdir -p /target/rootfs/lib/firmware/rtlwifi/ cp firmware/rtl8733bu_fw.bin /target/rootfs/lib/firmware/rtlwifi/ cp firmware/rtl8733bu_bt.bin /target/rootfs/lib/firmware/rtlwifi/ chmod 644 /target/rootfs/lib/firmware/rtlwifi/*.bin拷贝固件后建议做一次 md5 校验防止压缩工具或 Windows 换行符把 bin 文件改坏。文件名和内核版本强相关这个路径里的rtlwifi子目录是驱动内部硬编码的不能随便改。如果目标板是只读 rootfs可以把固件放到独立分区再通过符号链接指过来注意符号链接在 ramfs 里不会自动生效。驱动请求固件失败时dmesg 里常见request_firmware failed但定位时不要只查这一条。先用ls -l /lib/firmware/rtlwifi/确认文件真实存在再用strings 8733bu.ko | grep rtlwifi确认驱动编译时写入的固件路径。有些适配包会用-DDBG编译选项输出固件名实际路径和文件名以驱动的字符串表为准。3.2 NVRAM 参数决定天线配置与信号强度NVRAM 里存的是射频校准和板级配置包括 MAC 地址、天线数量、增益、信道规划。同一颗 RTL8733BU 在不同主板上天线数量和天线走线不一样直接照搬别人的配置信号强度可能差一截。驱动读取 NVRAM 的优先顺序是先查目标板上/lib/firmware/rtlwifi/下的同名配置再查驱动内置默认值。适配包自带的是公版天线的通用模板自己做板子时至少要把三个参数核对清楚。参数作用本场景建议ant_num天线数量与 PCB 实际天线走线对应1 或 2tx_power发射功率限制按模块认证值设置别乱调高country_code决定可用信道和功率上限CN / US / EU / 00修改 NVRAM 后要重新加载驱动才会生效ifconfig wlan0 down rmmod 8733bu modprobe 8733bu注意 NVRAM 里有一部分和校准数据相关量产的模组出厂时会烧录到芯片 OTP 区域驱动加载时会优先读 OTP。如果外部 NVRAM 和 OTP 冲突以 OTP 为准。碰到信号弱的问题先把外部 NVRAM 临时改名让驱动走 OTP 默认值对比一下差异再决定要不要覆盖。还需要注意 Linux 4.9 内核上 crda 的行为。如果 rootfs 里没装 wireless-regdb即使 NVRAM 写了 CN实际生效的监管域可能还是 005G 信道会被屏蔽。常见做法是在启动脚本里显式执行iw reg set CN并把 regulatory.bin 装进/lib/crda/目录。这一步不做后面排查 5G 频段问题时大概率会浪费半天时间。3.3 蓝牙与 WiFi 共存依赖的固件加载顺序RTL8733BU 是 WiFi 和蓝牙双模 combo 芯片。WiFi 驱动会顺带把蓝牙的 USB HCI 口初始化但这个初始化依赖特定时序。加载顺序乱了蓝牙可能起不来或者 WiFi 吞吐被蓝牙抢占。适配包里的启动脚本一般把蓝牙固件加载放在 WiFi 固件之后再通过厂商私有 HCI 命令配置共存参数。判定共存是否正常看两处hciconfig hci0 up能成功且iw dev wlan0 scan不出现频繁扫描中断。如果先 up 蓝牙再 up WiFi 时出现互相踢掉对方的现象把加载顺序改成 WiFi 先起来再启动蓝牙协议栈稳定性会明显改善。WiFi 驱动里和 HCI 命令相关的实现集中在 hal 目录不要手动去改里面的 opcode 枚举除非你已经拿到对应芯片的蓝牙固件 release note。实际项目中遇到过蓝牙只扫到少量设备、WiFi 同时掉速的情况原因就是 HCI 固件版本和 WiFi 驱动里 lock 的版本不匹配。这种情况下优先换固件文件而不是改驱动代码。固件版本号一般写在 bin 文件的头部可以用hexdump -C查看前 16 字节和 dmesg 打印的版本号对照。4. 适配 MC6810 平台的关键改动电源、端点与 USB 挂起策略4.1 电源时序与复位脚控制MC6810 主板给 WiFi 模组供电很少是简单对接 USB 5V 就完事实际项目里常见 LDO 加 GPIO 做使能还有复位脚控制。硬件设计上复位脚极性有高有效也有低有效驱动里的输出电平和设备树里的 GPIO 配置必须对齐。先看原理图上 EN 和 RESET 是否独立再决定时序怎么写。常见做法是设备树里申请 GPIO然后在驱动加载阶段按顺序拉电平usb1 { status okay; }; gpio { wifi_en { gpio gpio 88 GPIO_ACTIVE_HIGH; }; };这是示意性写法实际落地时驱动会通过 gpiod 接口控制输出时序建议先拉高 PWREN延时 10ms再拉高 CHIP_EN再延时 10ms 等待内部稳压器稳定。如果省略这段延时芯片上电未稳USB 枚举时表现是第一次获取描述符失败。这种问题很难直接定位因为 dmesg 里只显示cannot enable. Maybe the USB cable is bad?这类误导性信息。看到这个错误先怀疑电源时序再查线材和 VBUS。调试电源时序时用示波器同时抓两路GPIO 和模组电源输出。如果 GPIO 拉高后电源有毛刺说明 LDO 的 EN 脚滤波没做好。板子上空间紧张时很多人会省掉 EN 脚的 RC 滤波结果就是低温或快速上下电时 WiFi 间歇性枚举失败这类问题用软件是很难绕过去的。4.2 USB 端点带宽与传输模式配置驱动默认会按芯片标准的端点配置做匹配但 MC6810 的 USB Host 控制器在某些 SoC 实现上只支持有限的端点速率需要把驱动中的端点设置与实际设备描述符对齐。在板子上用 lsusb 确认lsusb -t lsusb -v | grep -E bInterfaceClass|bEndpointAddress|wMaxPacketSize从输出里找到 RTL8733BU 对应的设备描述符记录各端点的 bEndpointAddress 和 wMaxPacketSize然后对比驱动源码里初始化 USB 配置的数组。常见差异是在 High-Speed 模式下 isoc 端点的最大包长被缩小导致上行吞吐掉到 20Mbps 左右。调整方式是修改驱动中控制 isoc 单次传输最大包长的宏grep -R MAX_ISOC include/ | head找到宏定义后在合理范围内把值调大重新编译驱动。这个宏控制单次 isoc 传输的载荷大小数值越大吞吐越高但受 SoC USB 控制器预算限制。带宽不足时收包丢包率会明显上升通过cat /proc/net/dev看 drop 列能判断。我一般会在 512 和 1024 两个档位各试一遍选择丢包最少的一个而不是盲目拉到最大。另外注意 USB 描述符里如果报告的是 Full-Speed 而不是 High-Speed问题出在 ID 脚检测。RTL8733BU 的 USB 识别依赖 ID 电阻量产板把 ID 脚悬空或接错芯片会降级到 Full-Speed。这种问题在驱动里怎么调都没用必须回到硬件确认 ID 引脚的上下拉电阻。4.3 关闭 USB Autosuspend防止睡眠后掉线MC6810 这类带电源管理的平台默认会对 USB 设备做 autosuspend。WiFi 网卡在空闲时进入挂起唤醒后网络栈没有完整恢复表现是网卡还在但 ping 不通 AP。有两种处理方式推荐直接用内核参数禁掉usbcore.autosuspend-1把这一项加到目标板 cmdline 或 U-Boot 的 bootargs重启后确认cat /sys/module/usbcore/parameters/autosuspend_delay_ms输出 -1 表示已经禁用自动挂起。如果不想动内核启动参数可以在运行时对设备单独关闭echo on /sys/bus/usb/devices/1-1/power/control cat /sys/bus/usb/devices/1-1/power/runtime_status注意设备路径要按实际总线拓扑找到。主板 USB 端口如果是 1-1Hub 下接的 WiFi 可能是 1-1.2不要只改根端口。runtime_status 输出 active 而不是 suspended说明已经生效。项目里如果既想省电又不希望掉线可以做带超时的保活机制每 30 秒发一次空数据包或者在驱动电源管理回调里把 USB 设备标记为不可挂起。我自己的习惯是嵌入式 WiFi 场景直接关掉 autosuspend省得后面测试团队报低概率掉线问题。5. 移植踩坑实录5 个常见问题的现象、原因与处理5.1 insmod 报 version magic mismatch现象拿着适配包预编译好的 8733bu.ko往同一内核版本的板子上 insmod却报version magic 4.9.138 SMP mod_unload ARMv7 should be 4.9.138 SMP preempt mod_unload ARMv7 p2v8。原因vermagic 不只看内核版本号还包含抢占模式、ARM 的 p2v8 重定位特性等编译选项。不同 SDK 对同一个 4.9.138 编译出来的内核preempt 状态可能不同。预编译 .ko 在这个场景下最容易栽跟头。解决不要试图用 modprobe 的--force绕过版本检查那是给自己埋雷。回到开发机用与内核源码相同工具链、相同内核目录重新编译一次编完用 modinfo 对比 vermagic 关键字段完全一致后再部署。5.2 wlan0 起不来或扫描列表为空现象ifconfig wlan0 up不报错但iw dev wlan0 scan永远返回空列表dmesg 里出现Firmware Request failed之类的信息。原因固件文件没放到位或文件名和驱动预期不一致。驱动在 request_firmware 时用的是它内部硬编码的相对路径文件不在这条路径下就直接跳过不会给默认值。解决先按驱动二进制里的字符串表找到预期的固件路径检查 rootfs 下文件是否真实存在再检查权限是否为 644。如果文件是从 Windows 拷贝进去的确认 bin 没有被工具转成文本格式用file命令看一眼就能确认。5.3 WiFi 正常但蓝牙扫描不到广播现象hciconfig hci0 up成功但扫描列表始终为空广播包完全抓不到。原因RTL8733BU 的蓝牙固件加载有时序要求WiFi 驱动先上电后蓝牙固件下载时序被共存初始化打断HCI 命令被芯片丢弃。解决把加载顺序固定为 WiFi 先、蓝牙后检查驱动里的 coex 开关是否被编译选项关闭。如果适配包默认顺序是正常的就不要自己改启动脚本里的 insmod 顺序乱改顺序是典型的自找麻烦。5.4 睡眠唤醒后 ping 不通ifconfig 看 wlan0 还在现象平台进入 suspend 再唤醒后WiFi 指示灯正常但 ping 网关 100% 丢包必须 rmmod 再 modprobe 一次才能恢复。原因USB autosuspend 把 WiFi 设备挂起后恢复时驱动没有重新走 802.11 关联流程或者 AP 侧已经把该 client 踢掉而驱动仍保留旧状态。解决先按 4.3 节的处理关掉 usbcore autosuspend。如果问题依旧在驱动源码的 suspend 和 resume 回调里加日志确认 suspend 时是否进入了 disconnect 分支。特别注意某些 define 被错误打开时驱动会把挂起当成断开处理。5.5 5G 频段一个 AP 都搜不到2.4G 正常现象同一块板子2.4G 热点正常连5G 列表全空NVRAM 里country_code已经改成 CN。原因5G 受监管域限制Linux 的 cfg80211 加载监管域数据库失败时会默认禁用所有 5G 频道而 2.4G 的 1~11 信道不受影响。另一种可能是天线没接好5G 信号衰减比 2.4G 严重得多看起来也是搜不到任何热点。解决先在启动阶段确认iw reg set CN执行成功再用iw phy phy0 info查看 Band 2 的可用信道列表。两个都正常后再怀疑天线座虚焊、天线阻抗不匹配。不要一上来就改 NVRAM那只会掩盖真正的问题。6. 验证与信号调优从驱动日志到吞吐实测6.1 启动后先确认四件事驱动移植是否真正落地不看你编译有没有报错而是看启动日志和无线接口状态。我每次上板都按固定顺序检查四步dmesg | grep -i rtl8733 iw dev iw phy phy0 info | head -20 cat /proc/net/dev第一步看芯片是否完成枚举和固件加载dmesg 里会打印固件版本和 MAC 地址第二步确认 wlan0 接口存在如果只有 phy 没有接口说明驱动没有创建默认 STA 接口需要手动执行iw phy phy0 interface add wlan0 type managed第三步看 phy 支持的频段Band 1 是 2.4GBand 2 是 5G缺一个就从 NVRAM 和 regdb 入手第四步看 drop 字段接收丢包率持续大于 1% 就要查端点和电源。这四步走完驱动层面的状态基本透明了再往下才谈得上信号调优。6.2 连上 AP 之后的吞吐与天线调优连接和吞吐验证我一般用 wpa_supplicant 加 iperf3wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf iw dev wlan0 link iperf3 -siperf3 在板子上跑 server电脑端跑 client测 TCP 吞吐时先连续跑 60 秒看平均值而不是峰值。达不到预期吞吐时按优先级排查三件事一是天线。RTL8733BU 这类芯片的射频前端对天线净空区很敏感天线走线要保证 50 欧姆阻抗净空区不要铺铜。同一块板子天线位置挪 5mm吞吐可能差 30%这不是玄学是射频仿真里能看到的差异。二是供电。模组瞬间发射电流比较大LDO 输出能力不足时会在高功率档位掉吞吐。用示波器抓 3.3V 在打流时的跌落低于 3.15V 就要加大储能电容或换成 DCDC 供电。三是 NVRAM 的 tx_power 限幅。量产模组出厂有认证功率值不要为追求信号强度盲目调高天线匹配不好时调高功率只会增加误码率不会提升实际吞吐。第一次在这个平台调 RTL8733BU 时我被“看起来一切正常但 5G 扫描为空”折腾了整整两天最后发现只是 regdb 没装、iw reg set CN没执行。从那以后我每次换平台都会强制按 6.1 的四步清单走一遍再谈吞吐验证这个习惯帮我省下了很多重复排障的时间。这份适配包里的编译脚本和 NVRAM 我已经整理好放进了下载区需要的直接取希望帮到你。本文还有配套的精品资源点击获取