拓冰建站拓冰建站
首页 / 资讯中心 / 正文

RTL8189FS驱动移植实战:新内核编译报错修复与WiFi联网指南

简介这是Realtek官方发布的RTL8189FS无线网卡Linux驱动包面向嵌入式开发、驱动移植及使用海思平台的设备厂商解决在Linux及Android系统上适配与启用该型号WiFi模块的问题。压缩包共45个文件大小约15.53MB以PDF文档、gz/tgz源码压缩包、diff补丁、conf配置文件、txt说明、sh脚本等构成既包含驱动源码与编译脚本也有适用于Android 4.4、5.x、8.0、9.x等版本的SDK和wpa_supplicant源码便于按需选择对应内核分支。文档部分覆盖编译安装、Station/SoftAP模式、WOW、TDLS、P2P等场景的配置与调试说明并附带认证测试与功率节省等参考。资源面向有一定Linux驱动基础的开发者可直接在目标平台上编译模块、加载固件并实现无线连接。目前已有995人浏览学习适合需要在非标准平台或Android系统上移植RTL8189FS驱动、快速查阅官方配置指南的工程师使用。 拿到RTL8189FS_linux_v5.7.9_35795.20191128.zip这个文件名的压缩包玩过嵌入式Linux的朋友应该一眼就能认出它的身份——这是瑞昱Realtek官方发布的 RTL8189FS WiFi 模块 Linux 驱动源码驱动版本 v5.7.92019年11月28日打包。这块芯片是 SDIO 接口、2.4G 单频、802.11b/g/n速率最高到 150Mbps在国产开发板、平板、智能网关和物联网设备里非常常见。这篇文章我会把从解压到正常联网的完整流程拆开讲清楚重点说官方老驱动在新内核上编译时怎么改、有哪些坑适合正在做嵌入式Linux项目、或者手头有全志/瑞芯微/晶晨方案开发板需要接 RTL8189FS 的同学参考。1. 这个压缩包到底是什么能帮你解决什么问题1.1 RTL8189FS芯片与官方驱动版本说明RTL8189FS 是瑞昱一颗非常经典的 SDIO 接口 WiFi 芯片很多国产方案的板卡上都能看到它。它只支持 2.4GHz 频段1T1R 单天线支持 802.11b/g/n20MHz/40MHz 带宽下理论速率最高 150Mbps。对大多数 IoT 场景来说这个速率完全够用而且它驱动源码开放、采购成本低、外围电路简单所以大量出现在低成本安卓平板、Linux 开发板、网络摄像头和工控设备里。驱动版本号v5.7.9容易让人误以为和内核版本有关其实这里指的是瑞昱官方驱动自己的版本号发布时间是 2019 年 11 月 28 日构建编号 35795。瑞昱官方驱动包的命名规则基本统一芯片型号_linux_驱动版本号_构建编号.日期.zip。这个包里的代码官方本来是适配 Linux 2.6.38 到 4.x 内核的如果你手里的内核版本比较新比如 5.4、5.10、6.1直接编译基本都会报错这部分我会在第 3 节详细说。1.2 源码包结构和编译入口解压后你会看到一个RTL8189FS/目录里面主要的子目录有core/驱动核心逻辑协议处理、帧收发都在这里hal/硬件抽象层包含芯片底层的寄存器操作和 RF 配置os_dep/操作系统适配层负责和 Linux 内核网络的对接platform/平台相关代码firmware/固件文件目录里面有个rtlwifi/子目录Makefile顶层编译入口README.md官方说明文档编译入口就是顶层的Makefile驱动最终产出是一个8189fs.ko内核模块文件。在开始编译之前建议你先花两分钟看一下README.md和Makefile的最前面几十行里面会写到支持的平台、依赖的内核版本、以及编译命令示例。老驱动一般默认是没有针对你的开发板配置好的所以Makefile一定得改。2. 动手编译前的准备环境与Makefile改造2.1 确认目标平台和内核版本编译一个 WiFi 驱动模块本质上就是在你的宿主机上借助目标平台的内核源码和交叉编译工具链生成一个.ko文件。动手前你必须确认三件事。第一目标板子的 CPU 架构。如果是 ARM 开发板比如全志 H3/H5、瑞芯微 RK3288/RK3399、晶晨 S905 这类宿主机上得装对应的交叉编译工具链比如arm-linux-gnueabihf-或aarch64-linux-gnu-如果是 x86 的软路由或者开发主机直接用本机的gcc就行。第二目标板内核的版本和配置。驱动加载到内核里符号要能对得上。拿到板子的内核源码先确认版本号make kernelversion或者直接在板子上执行uname -r也可以。如果板子跑的是 4.19 或更老的内核官方驱动改动会比较小如果是 5.10 以上那就要做好打补丁的准备了。第三内核头文件路径。编译模块需要用内核源码目录里的头文件和Module.symvers符号表所以我一般会把目标板的内核源码解压到宿主机某个固定目录比如/home/user/linux-kernel/kernel-5.10。没有源码的话至少也要有同版本的内核头文件包即linux-headers。2.2 修改Makefile的正确姿势官方驱动的 Makefile 检测平台逻辑很简单就是靠一组CONFIG_PLATFORM_xxx开关来选。打开后你会看到类似这样的内容CONFIG_PLATFORM_I386_PC n CONFIG_PLATFORM_ARM_RPI n CONFIG_PLATFORM_ARM_SUNXI n CONFIG_PLATFORM_ARM_WETEK n ... CONFIG_PLATFORM_I386_PC y注意有些版本里同一个变量会出现在多个位置你最终要找到那个ifeq ($(CONFIG_PLATFORM_XXX), y)的分支去改。以我常用的 ARM 小板为例我会把其中一个平台开关置 y然后指定架构、交叉工具链和内核路径CONFIG_PLATFORM_ARM_RPI y ifeq ($(CONFIG_PLATFORM_ARM_RPI), y) EXTRA_CFLAGS -DCONFIG_LITTLE_ENDIAN ARCH : arm CROSS_COMPILE : arm-linux-gnueabihf- KVER : 5.10.0 KSRC : /home/user/linux-kernel/kernel-5.10 endif如果只是想在 x86 主机上先编译一把验证代码问题就保留CONFIG_PLATFORM_I386_PC y并填好本机内核路径CONFIG_PLATFORM_I386_PC y ifeq ($(CONFIG_PLATFORM_I386_PC), y) EXTRA_CFLAGS -DCONFIG_LITTLE_ENDIAN ARCH : x86 CROSS_COMPILE : KVER : $(shell uname -r) KSRC : /lib/modules/$(KVER)/build endif改完之后直接执行make如果你的 Makefile 里KSRC写对了编译过程会在几十秒到几分钟内结束最终目录下会生成8189fs.ko。很多新手会在这里卡住看到一堆编译错误就直接放弃其实大多数错误都集中在我下面要讲的几个点上。3. 驱动移植到新内核高频编译错误与修复方案3.1 老驱动为什么编译不过瑞昱官方驱动包自带的代码大量直接访问内核结构体内部字段的写法。这些字段在 4.x 时代是存在的但到了 5.x、6.x 内核子系统重构后很多字段被删除、改名或者变成了不透明的访问函数。所以老驱动在新内核上编译不过是常态不是你操作错。最典型的几个变化定时器 API 全面重做init_timer这种旧的初始化函数被移除了struct net_device里的priv字段被干掉要求统一使用netdev_priv()proc 文件系统接口也改过几轮PDE_DATA这类宏在部分内版本里改名了。你要做的不是把内核换老而是把驱动里这些过时的 API 修到能过编译、且功能不变。3.2 常见错误对照表与处理思路我把这几年编译时遇到的高频报错整理成一张表按这个思路改五分钟内基本能过编译。报错信息根本原因解决办法error: ISO C90 forbids mixed declarations and code新内核默认编译选项更严格在 Makefile 里补EXTRA_CFLAGS -stdgnu99struct net_device has no member named priv内核已废弃netdev-priv改用netdev_priv(netdev)返回值类型转成自定义结构体指针struct timer_list has no member named data定时器回调接口重构用timer_setup(timer, callback, 0)初始化回调函数签名改为void callback(struct timer_list *t)再通过from_timer获取原结构体implicit declaration of function PDE_DATAproc API 变化换成pde_data(inode)或者加一行#define PDE_DATA(inode) pde_data(inode)做兼容proc_dir_entry has no member named owner新内核删除该字段直接注释掉相关赋值语句unknown field ndo_set_mac_address specified in initializer网卡操作结构体变化看内核具体版本把ndo_set_mac_address改成对应回调名或删掉该行implicit declaration of function in_atomic缺头文件在对应 .c 文件里加#include linux/hardirq.h这些改动里定时器是最容易漏的。老代码通常是这样写的init_timer(padapter-mlmepriv.dhcp_timer); padapter-mlmepriv.dhcp_timer.data (unsigned long)padapter; padapter-mlmepriv.dhcp_timer.function dhcp_timeout_handler; add_timer(padapter-mlmepriv.dhcp_timer);新内核里要改成timer_setup(padapter-mlmepriv.dhcp_timer, dhcp_timeout_handler, 0); add_timer(padapter-mlmepriv.dhcp_timer);回调函数同步改成void dhcp_timeout_handler(struct timer_list *t) { struct mlme_priv *pmlmepriv from_timer(pmlmepriv, t, dhcp_timer); struct adapter *padapter container_of(pmlmepriv, struct adapter, mlmepriv); ... }内核社区把定时器 API 收敛成一套统一接口之后驱动这边凡是用了旧写法的地方都得跟着改。项目里搜一下init_timer、setup_timer把所有出现的地方都处理掉基本就能过这一关。3.3 编译产物如何确认编译成功后会生成8189fs.ko。别急着拿去板子上 insmod先用file命令确认架构和你板子匹配file 8189fs.ko如果显示ARM aarch64而你的板子是 32 位 ARM那肯定没法用。再检查一下模块依赖modinfo 8189fs.ko这条命令会显示模块名、依赖的符号、vermagic 等信息。vermagic一行会包含内核版本号、SMP、PREEMPT 这些配置加载时如果和运行内核不匹配会报invalid module format这也是最常见的问题之一。如果你板子内核开了模块签名校验加载时会报Required key not available或Module signature verification failed。这种时候要么在编译内核时关闭CONFIG_MODULE_SIG要么给模块做本地签名不然驱动功能再对也起不来。4. 固件与设备树驱动之外的地基4.1 固件文件:少一个bin文件就前功尽弃很多人在驱动编译通过、insmod 也成功了但dmesg里一直报错WiFi 接口就是冒不出来。这个时候十有八九是固件文件没放对位置。RTL8189FS 芯片内部的 ROM 只负责最基础的启动流程完整的 WiFi 协议固件需要从文件系统加载。驱动加载时会去固定路径找固件具体路径取决于内核配置一般是/lib/firmware/rtlwifi/rtl8189fs.bin。如果找不到dmesg里会出现类似这样的日志rtl8189fs: Direct firmware load for rtlwifi/rtl8189fs.bin failed with error -2 rtl8189fs: Falling back to sysfs fallback plugin解决办法很简单把官方驱动包firmware/rtlwifi/rtl8189fs.bin这个文件复制到板子的/lib/firmware/rtlwifi/目录下然后重新加载驱动mkdir -p /lib/firmware/rtlwifi cp rtl8189fs.bin /lib/firmware/rtlwifi/ insmod 8189fs.ko有些发行版的固件目录是/usr/lib/firmware/用ls /lib/firmware确认一下根文件系统实际挂载路径别放错位置。这个文件别看小没有它 WiFi 接口基本不可能工作。4.2 设备树中SDIO WiFi的配置要点RTL8189FS 是 SDIO 接口芯片所以它挂在哪个 SDIO 控制器上、供电怎么控制、复位脚怎么拉这些都要在设备树里说清楚。以全志 H3 平台举例常见的做法是给 WiFi 模块单独配一个电源时序节点wifi_pwrseq: wifi_pwrseq { compatible mmc-pwrseq-simple; reset-gpios r_pio 0 7 GPIO_ACTIVE_LOW; post-power-on-delay-ms 200; }; mmc1 { pwrseq wifi_pwrseq; bus-width 4; non-removable; vmmc-supply reg_vcc3v3; status okay; };这里pwrseq节点会按照内核mmc-pwrseq-simple的流程先给 WiFi 模块上电再拉高复位脚并等待 200ms让芯片稳定下来。如果你板子上 WiFi 的电源不是常供的这个时序就很重要电源没稳定就访问 SDIO 总线会导致芯片枚举失败现象就是内核日志里只有mmc1: error -110这类超时错误。不同平台管脚名不一样瑞芯微的板子可能需要配pinctrl-0 wifi_enable_h之类的引脚复用节点。设备树这一块没有通用万能配置必须对着自己板子的原理图改 GPIO 编号别直接抄网上的 dts 片段抄了大概率点不亮。5. 加载驱动与WiFi联网实测5.1 insmod、dmesg与wlan0出现的时机驱动文件、固件、设备树都准备好之后就可以上板实测了。把8189fs.ko复制到板子任何一个目录执行insmod 8189fs.ko正常情况下的日志大概是这样的rtl8189fs: powered by chip rtl8189fs: register rtl8189fs as wlan0看到register rtl8189fs as wlan0就说明驱动和设备匹配成功无线接口已经注册。如果等了半天只有mmc1: new high speed SDIO card之类的内容说明 SDIO 层枚举到了设备但驱动和设备树没匹配上优先检查 compatible 和中断号配置。接口注册后执行ifconfig -a或ip link应该能看到wlan0。这时候先扫描一下周围网络确认射频链路正常iw dev wlan0 scan | grep SSID如果扫描结果为空先检查天线是否接好、射频开关配置是否正确不要急着怀疑驱动。5.2 用wpa_supplicant连接到路由器扫描正常后用 wpa_supplicant 连接自家路由器。推荐直接用命令行生成配置wpa_passphrase MyWiFi password123 /etc/wpa_supplicant.conf wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf -D nl80211然后请求 IPudhcpc -i wlan0如果能拿到 IP接着ping -I wlan0 192.168.1.1验证一下连通性。在这里给一个小提示官方驱动模块默认可能把wlan0的 802.11n 特性开得很激进如果你在 40MHz 带宽、或者加密方式不兼容的路由器上连接不稳定可以试试强制只使用 20MHz 带宽很多兼容性问题会消失。驱动通过iwpriv命令调整参数iwpriv wlan0 set bintolerant 1具体的参数名要在驱动源码的hal/目录里查不同版本略有差异。5.3 速率验证与稳定性判断联网成功只是第一步做产品还要看稳定性。我一般用 iperf3 持续打流来看速率和丢包iperf3 -c 192.168.1.100 -t 60 -i 5RTL8189FS 实测近距离 40MHz 带宽下TCP 单向吞吐能跑到 80~100Mbps 之间属于正常水平。如果打流时频繁掉包、速率剧烈波动优先怀疑供电和天线问题其次看是不是有 2.4GHz 频段的同频干扰。打流的同时可以观察dmesg如果出现大量tx timeout或者firmware reload的日志说明驱动在运行过程中异常复位了这种问题往往和电源纹波、SDIO 信号完整性、时钟不稳有关纯软件层面很难完全规避但可以尝试在设备树里把 SDIO 时钟降一档比如从 50MHz 降到 25MHz提高信号裕量。6. 实战避坑记录与问题速查6.1 几个容易让人卡住的小问题第一个坑是模块带依赖。官方驱动可能依赖内核里的cfg80211模块如果modinfo 8189fs.ko里看到依赖cfg80211而目标内核又把它编成了模块那 insmod 之前要先把cfg80211.ko加载好否则会报Unknown symbol。第二个坑是驱动和内核配置选项冲突。举个例子如果内核开启了CONFIG_CFG80211_WEXT而驱动自己也带了 wext 兼容层可能出现符号重复定义。这种问题不好排查我一般的做法是编译内核时保持比较保守的无线配置确认 RTL8189FS 官方驱动只依赖最基本的cfg80211。第三个坑是模块重名。如果你的板子还挂了别的 WiFi 模块比如 AP6212、RTL8723BS它们的驱动模块名也可能是wlan0加载顺序会把接口名抢走。加载完用dmesg看实际注册的接口名就行不要想当然认为一定是wlan0。6.2 快速排查思路遇到问题按下面的顺序排查避免乱试现象描述优先级排查项验证方法insmod 报invalid module format内核版本/配置不匹配对比modinfo的 vermagic 和板子uname -ainsmod 报Unknown symbol模块依赖缺失按 modinfo 显示的依赖逐个加载加载成功但没生成 wlan0固件缺失/设备树不匹配看dmesg搜firmware、mmc1关键字有 wlan0 但扫描不到网络天线/射频配置检查天线连接iw reg set CN设置合规区域连接路由器一直认证失败wpa_supplicant 配置错误重新生成配置确认密码正确-dd参数打印调试信息打流掉包严重供电不稳/信号干扰降低 SDIO 时钟换 20MHz 带宽外接供电测试排查的时候不要只盯着驱动本身很多问题其实是硬件或者内核配置层面引起的。把问题现象、内核日志、模块依赖关系这三个信息收集齐解决速度会快很多。最后分享一个我自己的习惯拿到官方驱动包之后第一件事不是直接 make而是先搜一下有没有人已经为这个芯片适配过新内核的补丁。RTL8189FS 这颗芯片在开源社区有多个维护很活跃的驱动项目很多老内核下的问题已经有人给出了完整修复。可以先在社区版驱动上跑通再回头看官方源码哪些地方需要改这样会少走很多弯路。我自己在 5.10 内核上适配这颗芯片时就是从官方驱动出发对照社区补丁逐个修改定时器、网络结构和 proc 接口的写法半天时间就稳定跑通了。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门