RTL8189FS WiFi 驱动移植与配置 文章封面

RTL8189FS WiFi 驱动移植与配置

硬件:iMX6ULL 开发板 + RTL8189FTV WiFi 模块(SDIO 接口)
内核:Linux 4.14
目标:编译 8189fs.ko,加载驱动,连接 WiFi 热点


一、硬件与驱动对应关系

芯片丝印驱动名称接口
RTL8189FTVrtl8189fsSDIO
RTL8189ESrtl8189esSDIO

RTL8189FTV 是 RTL8189FS 的不同封装变体(FTV = Fine pitch Thin package with exposed pad V-shape),内核驱动完全相同,使用 rtl8189fs 驱动。

该驱动是树外驱动(out-of-tree),不在 Linux 主线内核中,需要单独获取源码后集成到内核树。


二、系统层次结构

用户层:  wpa_supplicant / ifconfig / iwlist
         ↓
内核层:  cfg80211 / mac80211(Linux WiFi 协议栈)
         ↓
驱动层:  8189fs.ko(SDIO 设备驱动,注册到 mac80211)
         ↓
总线层:  MMC/SDIO 子系统
         ↓
硬件层:  iMX6ULL SDIO 控制器 → RTL8189FTV 芯片


三、驱动集成步骤

3.1 放置驱动源码

将 rtl8189FS 源码目录放入内核树:

drivers/net/wireless/realtek/rtl8189FS/
├── Kconfig
├── Makefile
├── core/
├── hal/
├── include/
├── os_dep/
└── platform/

3.2 修改上层 Makefile

编辑 drivers/net/wireless/realtek/Makefile,添加:

obj-$(CONFIG_RTL8189FS) += rtl8189FS/

3.3 修改上层 Kconfig

编辑 drivers/net/wireless/realtek/Kconfig,添加:

source "drivers/net/wireless/realtek/rtl8189FS/Kconfig"

3.4 通过 menuconfig 配置

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

路径:Device Drivers → Network device support → Wireless LAN → Realtek devices → RTL8189FS

选择 M(编译为模块),不选 Y(选 Y 会编译进内核,不生成 .ko 文件)。

3.5 编译模块

# 只编译该模块,速度快
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 
  M=drivers/net/wireless/realtek/rtl8189FS modules

# 编译完成后 .ko 文件在驱动目录下
ls drivers/net/wireless/realtek/rtl8189FS/8189fs.ko

3.6 拷贝到开发板

# 通过 NFS 或 scp 拷贝到开发板
cp drivers/net/wireless/realtek/rtl8189FS/8189fs.ko /nfsroot/


四、加载驱动

insmod 8189fs.ko

正常输出:

RTL871X: module init start
RTL871X: rtl8189fs v4.3.24.8_22657.20170607
RTL871X: rtw_ndev_init(wlan0) if1 mac_addr=30:4a:26:b0:b9:af
RTL871X: module init ret=0

⚠️ 加载时会出现 WARNING: possible recursive locking detected 警告,这是 RTL8189FS 驱动在 Linux 4.14 上的已知历史遗留问题(rtw_alloc_stainfo 和 rtw_alloc_macid 嵌套获取同类型自旋锁触发 lockdep 检测)。实际运行不会死锁,可忽略。

验证 wlan0 接口已创建:

ifconfig wlan0
# 或
ip link show wlan0


五、扫描与连接 WiFi

5.1 激活接口

ifconfig wlan0 up
# 内核会打印 "wlan0: link is not ready",正常现象(还未关联 AP)

5.2 扫描周围热点

iwlist wlan0 scan | grep ESSID

5.3 创建 wpa_supplicant 配置文件

cat > /etc/wpa_supplicant.conf << 'EOF'
ctrl_interface=/var/run/wpa_supplicant
network={
    ssid="你的WiFi名称"
    psk="你的WiFi密码"
    key_mgmt=WPA-PSK
}
EOF

注:该 rootfs 没有 wpa_passphrase 工具,需手动创建配置文件。

5.4 后台连接

wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf

连接成功的 dmesg 日志:

RTL871X: start auth
RTL871X: auth success, start assoc
RTL871X: assoc success
RTL871X: recv eapol packet      ← WPA2 四次握手开始
RTL871X: send eapol packet
RTL871X: set pairwise key camid:4, type:AES   ← 单播密钥
wlan0: link becomes ready
RTL871X: set group key camid:5, type:TKIP     ← 组播密钥

5.5 获取 IP

udhcpc -i wlan0
# 应输出:lease of 192.168.2.xxx obtained

⚠️ BusyBox udhcpc 的坑:lease obtained 只表示 DHCP 协商成功,但 BusyBox 的 udhcpc 依赖 /usr/share/udhcpc/default.script 将 IP 实际写入接口。若该脚本不存在,ifconfig wlan0 看不到 IPv4 地址。

解决方法:手动配置(将 xxx 替换为 udhcpc 获取到的实际 IP):

ifconfig wlan0 192.168.2.xxx netmask 255.255.255.0

5.6 配置默认路由

udhcpc 不一定自动添加默认网关,需手动补充:

# 添加默认网关
route add default gw 192.168.2.1 dev wlan0

# 验证路由表
route -n

注:若开发板同时接有 eth0(有线网络),路由表中会出现两条 192.168.2.0/24 路由,eth0 那条优先级更高(先添加)。局域网流量走 eth0,外网流量走 wlan0 默认路由,互不干扰。

5.7 配置 DNS

echo "nameserver 192.168.2.1" > /etc/resolv.conf

使用路由器作为 DNS 服务器(192.168.2.1),路由器会转发 DNS 查询到上游。也可填写其他 DNS,但需确认运营商未屏蔽该地址。


六、验证网络连通性

# ping 路由器(验证 wlan0 局域网通信)
ping -I wlan0 192.168.2.1 -c 3

# 验证外网 TCP 连接(最可靠)
wget -O /dev/null http://neverssl.com
# 输出 100% 下载完成即为外网畅通

⚠️ 注意事项:

  • 不要用 ping 测试外网:中国联通等运营商在 ISP 层面屏蔽 ICMP,ping 外网全部超时,但 HTTP 完全正常。
  • 不要用 wget http://baidu.com:百度会将 HTTP 重定向到 HTTPS,而 BusyBox 的 wget 不支持 HTTPS(无 SSL/TLS),会报 error getting response。改用 neverssl.com(永远不跳 HTTPS 的测试站)。

七、已知问题与说明

  • 外网连通性验证:ICMP 被运营商屏蔽;改用 wget -O /dev/null http://neverssl.com 验证,下载成功,外网畅通
  • ko 文件持久化:将 8189fs.ko 安装到 /lib/modules/$(uname -r)/ 并执行 depmod,实现 modprobe 加载
  • 开机自动连接:暂不配置,开发阶段手动连接即可(modprobe 8189fs → ifconfig wlan0 up → wpa_supplicant → udhcpc)

关联笔记

延伸阅读

WiFi 驱动可用吞吐测试验证效果,底层适配问题则常需回到内核与设备树。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部