在Android方案开发中,经常需要移植不同厂商不同型号的WiFi模块驱动,并与系统软件进行适配。模块厂商一般都会提供相应的开发文档以及驱动源码,我们需要做的就是将驱动源码编译成驱动模块ko文件,或者直接编进kernel中,我的项目中基本都是编译成ko驱动文件,方便不同型号的固件间替换文件即可。然后根据开发文档进行差异化适配,下面以在海思Hi3798MV200-android7.0适配RTL8733BU模块为例,整理记录整个流程。

厂商提供的源码及开发文档如上图目录,基本只需要关心三个地方,驱动源码、Android版本适配差异、wpa_supplicant(WiFi连接通讯相关)版本源码。

1.BoardConfig.mk中新增全局WiFi模块开关定义

代码路径:\HiSTBAndroidV600R003C00SPC020\device\hisilicon\Hi3798MV200\BoardConfig.mk

# RTL8188FTV
BOARD_WLAN_DEVICE_RTL8188FTV := n
# RTL8188EUS
BOARD_WLAN_DEVICE_RTL8188EUS := n
# RTL8188ETV
BOARD_WLAN_DEVICE_RTL8188ETV := n
# RTL8192EU
BOARD_WLAN_DEVICE_RTL8192EU := n
# RTL8821CU
BOARD_WLAN_DEVICE_RTL8821CU := y
# RTL8731BU新增
BOARD_WLAN_DEVICE_RTL8733BU := y 
# HI1131C
BOARD_WLAN_DEVICE_HI1131C := n



ifeq ($(BOARD_WLAN_DEVICE_RTL8821CU),y)
BOARD_WIFI_VENDOR := realtek
endif
#新增厂商定义
ifeq ($(BOARD_WLAN_DEVICE_RTL8733BU),y)
BOARD_WIFI_VENDOR := realtek
endif

#更据7.0开发文件定义wpa_supplicant版本等信息
#BOARD_WIFI_VENDOR := realtek

ifeq ($(BOARD_WIFI_VENDOR), realtek)
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl
BOARD_HOSTAPD_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_rtl
BOARD_WLAN_DEVICE := rtl8822bu  # 根据实际芯片选择
WIFI_DRIVER_MODULE_NAME := "wlan"
WIFI_DRIVER_MODULE_PATH := "/vendor/modules/wlan.ko"
WIFI_DRIVER_MODULE_ARG := "ifname=wlan0 if2name=p2p0"
WIFI_FIRMWARE_LOADER := "rtw_fwloader"
WIFI_DRIVER_FW_PATH_STA := "STA"
WIFI_DRIVER_FW_PATH_AP := "AP"
WIFI_DRIVER_FW_PATH_P2P := "P2P"
WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
endif

2.kernel.mk中新增对应模块驱动编译定义

代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\build\kernel.mk

#----------------------------------------------------------------------
# Update Wifi Drivers
#----------------------------------------------------------------------
WIFI_CFG := \
	CFG_HI_WIFI_DEVICE_RTL8188EUS=$(BOARD_WLAN_DEVICE_RTL8188EUS) \
	CFG_HI_WIFI_DEVICE_RTL8192EU=$(BOARD_WLAN_DEVICE_RTL8192EU) \
	CFG_HI_WIFI_DEVICE_RTL8812AU=$(BOARD_WLAN_DEVICE_RTL8812AU) \
	CFG_HI_WIFI_DEVICE_RTL8723BU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8723BU) \
	CFG_HI_WIFI_DEVICE_RTL8822BU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8822BU) \
	CFG_HI_WIFI_DEVICE_RTL8821AU=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8821AU) \
	CFG_HI_WIFI_DEVICE_MT7601U=$(BOARD_WLAN_DEVICE_MT7601U) \
	CFG_HI_WIFI_DEVICE_MT7662TE=$(BOARD_BLUETOOTH_WIFI_DEVICE_MT7662TE) \
	CFG_HI_WIFI_DEVICE_MT76X2U=$(BOARD_BLUETOOTH_WIFI_DEVICE_MT76X2TU) \
	CFG_HI_WIFI_DEVICE_QCA6174=$(BOARD_BLUETOOTH_WIFI_DEVICE_QCA6174) \
	CFG_HI_WIFI_DEVICE_HI1131C=$(BOARD_WLAN_DEVICE_HI1131C) \
	CFG_HI_WIFI_DEVICE_AP6XXX=$(BOARD_BLUETOOTH_WIFI_DEVICE_AP6356S) \
	CFG_HI_WIFI_DEVICE_RTL8822BEH=$(BOARD_BLUETOOTH_WIFI_DEVICE_RTL8822BEH) \
	CFG_HI_WIFI_DEVICE_RTL8188FU=$(BOARD_WLAN_DEVICE_RTL8188FTV) \
	CFG_HI_WIFI_DEVICE_RTL8821CU=$(BOARD_WLAN_DEVICE_RTL8821CU) \
     #新增CFG_HI_WIFI_DEVICE_RTL8733BU关联上一步BOARD_WLAN_DEVICE_RTL8733BU开关
	CFG_HI_WIFI_DEVICE_RTL8733BU=$(BOARD_WLAN_DEVICE_RTL8733BU) \
	CFG_HI_WIFI_MODE_STA=y CFG_HI_WIFI_MODE_AP=y

3.系统源码中WiFi驱动相关编译Makefile中新增模块驱动源码路径

代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\sdk\source\component\wifi\drv\Makefile

ifeq ($(CFG_HI_WIFI_DEVICE_RTL8821CU),y)
objects += usb_rtl8821cu
endif
#根据上一步定义的开关增加模块驱动源码路径目录名称
ifeq ($(CFG_HI_WIFI_DEVICE_RTL8733BU),y)
objects += usb_rtl8733bu
endif

然后在drv目录下新增刚才定义的usb_rtl8733bu目录,里面放置厂商提供的驱动源码文件夹,如下

usb_rtl8733bu创建Makefile文件,内容如下:

obj-m += rtl8733BU_WiFi_linux_v5.15.12-123-g23d8f6271.20240806_COEX20230616-330e/

4.修改驱动源码中的Makefile,根据自己实际情况,配置对应的平台信息,编译链路径等才能正确编译出驱动ko文件

源码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\bigfish\sdk\source\component\wifi\drv\usb_rtl8733bu\rtl8733BU_WiFi_linux_v5.15.12-123-g23d8f6271.20240806_COEX20230616-330e\Makefile

选择平台-CONFIG_PLATFORM_HISILICON_HI3798

选择自己源码中kernel路径和编译链路径:

至此,编译kernel就可以得到驱动文件8733bu.ko

源码根目录执行:make kernel -j32 2>&1 | tee kernel.log

得到kernel.img和system/lib/module/8733bu.ko

5.编译厂商提供的rtw_fwloader和wpa_supplicant,用于WiFi连接通讯

使用 Realtek 提供的 wpa_supplicant_8_N_7.0_rtw 替换系统默认版本:

  1. 删除原 external/wpa_supplicant_8

  2. 解压 Realtek 提供的版本并重命名为 wpa_supplicant_8

  3. 编译后得到/system/bin/wpa_supplicant

使用厂商提供给rtw_fwloader源码hardware/realtek拷贝到源码对应位置,编译后得到

/sysetm/bin/rtw_fwloader

6.init.xxx.rc 添加服务,开机启动上一步得到rtw_fwloader和wpa_supplicant的执行文件

代码路径:HiSTBAndroidV600R003C00SPC020\device\hisilicon\Hi3798MV200\etc\init.Hi3798MV200.rc

service rtw_fwloader /system/bin/rtw_fwloader
    class main
    disabled
    oneshot

service wpa_supplicant /system/bin/wpa_supplicant \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot

service p2p_supplicant /system/bin/wpa_supplicant \
    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
    -e/data/misc/wifi/entropy.bin -N \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    -g@android:wpa_wlan0
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot

service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL
    class main
    disabled
    oneshot

service dhcpcd_p2p /system/bin/dhcpcd -aABKL
    class main
    disabled
    oneshot

7.修改libhardware_legacy开机自动加载对应WiFi模块驱动

这一步可参考之前文章Android 开机自动加载新wifi模块驱动

代码目录:HiSTBAndroidV600R003C00SPC020\hardware\libhardware_legacy\include\hardware_legacy\wifi.h

typedef enum {
    WIFI_RALINK_MT7601U,
    WIFI_REALTEK_RTL8188EUS,
    WIFI_REALTEK_RTL8188ETV,
    WIFI_REALTEK_RTL8192EU,
    WIFI_REALTEK_RTL8812AU,
    WIFI_REALTEK_RTL8723BU,
    WIFI_MEDIATEK_MT7632U,
    WIFI_MEDIATEK_MT7662U,
    WIFI_MEDIATEK_MT7612U,
    WIFI_REALTEK_RTL8821AU,
    WIFI_ATHEROS_QCA6174,
    WIFI_REALTEK_RTL8822BU,
    WIFI_REALTEK_RTL8822BE,
    WIFI_HISI_HI1131C,
    WIFI_AMPAK_AP6356S,
    WIFI_REALTEK_RTL8188FU,
    WIFI_MEDIATEK_MT7662TE,
    WIFI_MEDIATEK_MT7662TU,
    WIFI_REALTEK_RTL8821CU,
    WIFI_REALTEK_RTL8731BU, //新增
    WIFI_INVALID_DEVICE = ~0x0 ,
} wifi_id_e;

kl90x\HiSTBAndroidV600R003C00SPC020\hardware\libhardware_legacy\wifi\wifi.c

static wifi_modules_s sta_drivers[] = {
    {DRIVER_MODULE_MT7601U_STA},      // MediaTek MT7601U
    {DRIVER_MODULE_RTL8188EUS},       // RealTek RTL8188EUS
    {DRIVER_MODULE_RTL8188EUS},       // RealTek RTL8188ETV
    {DRIVER_MODULE_RTL8192EU},        // RealTek RTL8192EU
    {DRIVER_MODULE_RTL8812AU},        // RealTek RTL8812AU
    {DRIVER_MODULE_RTL8723BU},        // RealTek RTL8723BU
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7632U
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7662U
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7612U
    {DRIVER_MODULE_RTL8821AU},        // RealTek RTL8821AU
    {DRIVER_MODULE_QCA6174},          // Atheros QCA6174
    {DRIVER_MODULE_RTL8822BU},        // RealTek RTL8822BU
    {DRIVER_MODULE_RTL8822BE},        // RealTek RTL8822BE
    {DRIVER_MODULE_HI1131C},          // Hisi Hi1131C
    {DRIVER_MODULE_AP6356S_STA},     // AMPAK AP6356S
    {DRIVER_MODULE_RTL8188FU},       // RealTek RTL8188FTV
    {DRIVER_MODULE_MT7662TE},         //MediaTek MT7662TE
    {DRIVER_MODULE_MT7662TU},          //MediaTek MT7662TU
    {DRIVER_MODULE_RTL8821CU},          //RealTek RTL8821CU
    {DRIVER_MODULE_RTL8731BU}          //RealTek RTL8731BU
};

static wifi_modules_s sta_drivers[] = {
    {DRIVER_MODULE_MT7601U_STA},      // MediaTek MT7601U
    {DRIVER_MODULE_RTL8188EUS},       // RealTek RTL8188EUS
    {DRIVER_MODULE_RTL8188EUS},       // RealTek RTL8188ETV
    {DRIVER_MODULE_RTL8192EU},        // RealTek RTL8192EU
    {DRIVER_MODULE_RTL8812AU},        // RealTek RTL8812AU
    {DRIVER_MODULE_RTL8723BU},        // RealTek RTL8723BU
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7632U
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7662U
    {DRIVER_MODULE_MT7632U},          // MediaTek MT7612U
    {DRIVER_MODULE_RTL8821AU},        // RealTek RTL8821AU
    {DRIVER_MODULE_QCA6174},          // Atheros QCA6174
    {DRIVER_MODULE_RTL8822BU},        // RealTek RTL8822BU
    {DRIVER_MODULE_RTL8822BE},        // RealTek RTL8822BE
    {DRIVER_MODULE_HI1131C},          // Hisi Hi1131C
    {DRIVER_MODULE_AP6356S_STA},     // AMPAK AP6356S
    {DRIVER_MODULE_RTL8188FU},       // RealTek RTL8188FTV
    {DRIVER_MODULE_MT7662TE},         //MediaTek MT7662TE
    {DRIVER_MODULE_MT7662TU},          //MediaTek MT7662TU
    {DRIVER_MODULE_RTL8821CU},          //RealTek RTL8821CU
    {DRIVER_MODULE_RTL8731BU}          //RealTek RTL8731BU
};


#define DRIVER_MODULE_RTL8821CU   2,  \
{ \
    {"cfg80211",MODULE_PATH"cfg80211.ko","","cfg80211 "}, \
    {"rtl8821cu",MODULE_PATH"rtl8821cu.ko","ifname=wlan0 if2name=p2p0","rtl8821cu "} \
}

#define DRIVER_MODULE_RTL8731BU   2,  \
{ \
    {"cfg80211",MODULE_PATH"cfg80211.ko","","cfg80211 "}, \
    {"8733bu",MODULE_PATH"8733bu.ko","ifname=wlan0 if2name=p2p0","8733bu "} \
}

编译得到/system/lib/libhardware_legacy.so,至此整个适配流程完成了。

手动调试命令:

1.检测WiFi设备:#lsusb 或 cd /sys/bus/usb/devices(设备名称在hardware\libhardware_legacy\wifi\wifi.c)
2.加载驱动:进入ko目录 cd /system/lib/modules
a.加载CFG80211驱动:insmod cfg80211.ko
b.加载WiFi驱动:insmod rt18188eu.ko
c.查看WiFi网口:iwconfig (有wlan0 网口说明WiFi初始化成功)
d.启动WiFi网口:ifconfig wlan0 up
e.扫描WiFi列表:iwlist wlan0 scan

wifi调试相关
1. 添加模块
insmod /system/vendor/modules/8733bs.ko ifname=wlan0 if2name=p2p0
2. 启动wpa_supplicant
wpa_supplicant -D nl80211 -i wlan0 -c /data/misc/wifi/wpa_supplicant.conf -B

wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B
3. 扫描二维码
wpa_cli scan

模块与系统通讯逻辑:

Android中Wifi里Frameworks和Wpa_Supplicant交互的方式
Wifi中主要通过WifiNative与WPAS通信。如果想从framework层控制WPAS层的OKC,步骤如下:

WifiNative–>com_android_server_wifi_WifiNative.cpp–>wifi.c–>wpa_supplicant.c
com_android_server_wifi_WifiNative.cpp是WifiNative的JNI,
wifi.c是底层wifi_start_supplicant() native方法的定义,
wifi.c中通过wifi_send_command() 使用ctrl_conn 中的wpa_ctrl 对象向WPAS 发送命令并接收回复。
wifi_ctrl_recv() 使用monitor_conn 中的wpa_ctrl 对象接收来自WPAS 的消息:

代码路径:

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
/frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp
/hardware/libhardware_legacy/wifi/wifi.c
/external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant.c

# Android 12上
frameworks/opt/net/wifi/libwifi_hal/rk_wifi_ctrl.cpp
4. wifi添加模块处理
android/hardware/libhardware_legacy/wifi_hardware_info/wifi_hardware_info.c

Logo

海思 HiSpark 开发者社区是上海海思为开发者搭建的内容和交流平台,依托完备芯片解决方案、专业开发环境、开源/开放的软件资源与社区技术内容,构建完整服务生态开发者的闭环体系。

更多推荐