rt2870 usb wifi在mx53 android平台上的移植
USB WIFI在linux平台下的移植教程网上很多,但是在android上的移植,完整的教程很少,移植这个驱动整整花了一个星期的时间,以下是
这个星期下来详细的移植笔记。
一:编译wifi驱动源码,生成ko文件
由于在linux的根文件系统下存在/etc目录,而android的根目录下,/etc是从/system/etc下链接过来的,因此
需要修改wifi源码,让驱动从/system/etc下寻找配置文件。
寻找/etc/Wireless文件,找到如下文件存在,全修改为/system/etc/Wireless:
root@lqm:/opt/program/tools/RT3070_Linux_STA# grep -r '/mnt/etc' ./
./include/os/rt_drv.h:#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat"
./include/os/rt_drv.h:#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat"
./include/os/rt_drv.h:#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
./include/os/rt_linux.h:#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat"
./include/os/rt_linux.h:#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat"
./include/os/rt_linux.h:#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
./os/linux/Makefile.6:DAT_PATH = /etc/Wireless/RT$(CHIPSET_DAT)STA
./os/linux/Makefile.6: $(shell [ ! -f /etc/Wireless ] && mkdir /etc/Wireless)
二进制文件 ./os/linux/rt_profile.o 匹配
./os/linux/Makefile:DAT_PATH = /mnt/etc/Wireless/RT$(CHIPSET_DAT)STA
./os/linux/Makefile: $(shell [ ! -f /etc/Wireless ] && mkdir /etc/Wireless)
二进制文件 ./os/linux/rt3070sta.o 匹配
二进制文件 ./os/linux/rt3070sta.ko 匹配
./os/linux/Makefile.4:DAT_PATH = /etc/Wireless/RT$(CHIPSET_DAT)STA
./os/linux/Makefile.4: $(shell [ ! -f /etc/Wireless ] && mkdir /etc/Wireless)
二进制文件 ./common/rtmp_init_inf.o 匹配
./RT2870STACard.dat:00CARDID=/etc/Wireless/RT2870STA/RT2870STA1.dat
./RT2870STACard.dat:01CARDID=/etc/Wireless/RT2870STA/RT2870STA2.dat
./RT2870STACard.dat:02CARDID=/etc/Wireless/RT2870STA/RT2870STA3.dat
./RT2870STACard.dat:00MAC00:0E:2E:C3:D0:48=/etc/Wireless/RT2870STA/RT2870STA1.dat
./RT2870STACard.dat:01MAC00:40:F4:FF:AA:40=/etc/Wireless/RT2870STA/RT2870STA2.dat
./RT2870STACard.dat:02MAC00:0C:43:10:11:5C=/etc/Wireless/RT2870STA/RT2870STA3.dat
./RT2870STACard.dat:00CARDTYPEbgn=/etc/Wireless/RT2870STA/RT2870STA1.dat
./RT2870STACard.dat:01CARDTYPEbgn=/etc/Wireless/RT2870STA/RT2870STA2.dat
./RT2870STACard.dat:02CARDTYPEabgn=/etc/Wireless/RT2870STA/RT2870STA3.dat
root@lqm:/opt/program/tools/RT3070_Linux_STA#
二:修改init.rc文件
直接修改out/..../root下的init.rc文件:
# mkdir /data/misc/wifi 0770 wifi wifi #lqm changed property.
mkdir /data/misc/wifi 0771 wifi wifi
# chmod 0770 /data/misc/wifi
chmod 0771 /system/etc/wifi #lqm changed path
#chmod 0660 /data/misc/wifi/wpa_supplicant.conf #lqm changed path
chmod 0660 /system/etc/wifi/wpa_supplicant.conf
chown wifi wifi /system/etc/wifi/wpa_supplicant.conf #lqm added.
on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain
mkdir /data/system 0775 system system
mkdir /data/system/wpa_supplicant 0771 wifi wifi # lqm added.
# Set DNS
#setprop net.dns1 192.168.128.2 #lqm changed.
setprop net.dns1 192.168.1.1
# Prepare for wifi
setprop wifi.interface ra0
# mkdir /data/misc/wifi/sockets 0770 wifi wifi
mkdir /data/misc/wifi/sockets 0771 wifi wifi #lqm changed property
# mkdir /data/misc/dhcp 0770 dhcp dhcp
# chown dhcp dhcp /data/misc/dhcp
mkdir /data/misc/dhcp 0771 system system #lqm changed.
# lqm changed.
service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -ira0 -c /system/etc/wifi/wpa_supplicant.conf
group system wifi inet
disabled
oneshot
# lqm changed.
service dhcpcd /system/bin/dhcpcd ra0
group system dhcp
disabled
oneshot
默认init.rc中全使用的wlan0,而rt2860的网络名称为ra0,因此需全替换为ra0。
三:修改hardware/libhardware_legacy/wifi/wifi.c文件。
重新定义WIFI_DRIVER_MODULE_PATH和WIFI_DRIVER_MODULE_NAME宏,定义如下:
#ifndef WIFI_DRIVER_MODULE_PATH
#define WIFI_DRIVER_MODULE_PATH "/system/lib/modules/rt3070sta.ko"
#endif
#ifndef WIFI_DRIVER_MODULE_NAME
#define WIFI_DRIVER_MODULE_NAME "rt3070sta"
#endif
wifi.c用于启动时自动加载ko模块,这里暂时使用手动加载的方法,后续更新自动加载功能。
四:在/device/fsl/imx53_loco/BoardConfig.mk文件中增加一行(根据你的无线网卡类型来设置):
BOARD_WPA_SUPPLICANT_DRIVER := WEXT
同时屏掉相关信息,修改后部分代码如下:
#WIFI_DRIVER_MODULE_PATH := "/system/lib/modules/ar6000.ko" #lqm changed.
WIFI_DRIVER_MODULE_PATH := "/system/lib/modules/rt3070sta.ko"
WIFI_DRIVER_MODULE_ARG := ""
#WIFI_DRIVER_MODULE_NAME := "ar6000" #lqm changed.
WIFI_DRIVER_MODULE_NAME := "rt3070sta"
WIFI_FIRMWARE_LOADER := ""
#WPA_SUPPLICANT_VERSION := VER_0_6_ATHEROS #lqm masked.
#BOARD_WLAN_ATHEROS_SDK := system/wlan/atheros/AR6kSDK.3.0_RC.298 #lqm masked.
#BOARD_WLAN_CHIP := AR6003 #lqm masked.
BOARD_WPA_SUPPLICANT_DRIVER := WEXT
注意WPA_SUPPLICANT_VERSION一定要屏蔽,否则将使用针对atheros的wpa_supplicant。
五:单独编译wpa_supplicant,将默认的wpa_wupplicant for atheros的文件替换掉:
source build/envsetup.sh
mm external/wpa_supplicant/ PRODUCT-imx53_loco-eng
这时将会在out/..../system/bin下生成新的wpa_supplicant文件。
如果使用默认的wpa_supplicant,执行时将会弹出如下错误:
===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 663
ioctl[SIOCSIWGENIE]: Operation not su===>rt_ioctl_giwscan. 4(4) BSS returned, 3
pported on transport endpoint
===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 663
ioctl[SIOCSIWGENIE]: Operation not ===>rt_ioctl_giwscan. 4(4) BSS returned, da3
supported on transport endpoint
===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 663
ioctl[SIOCSIWGENIE]: Operation not su===>rt_ioctl_giwscan. 4(4) BSS returned, 3
pported on transport endpoint
===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 663
ioctl[SIOCSIWGENIE]: Operation not su===>rt_ioctl_giwscan. 4(4) BSS returned, 3
pported on transport endpoint
===>rt_ioctl_giwscan. 5(5) BSS returned, data->length = 843
ioctl[SIOCSIWGENIE]: Operation not ===>rt_ioctl_giwscan. 5(5) BSS returned, da3
supported on transport endpoint
而且反复执行。
六:新建wpa_supplicant.conf文件,内容如下:
# WPA-PSK/TKIP
ctrl_interface=/system/bin/wpa_supplicant
network={
ssid="armeasy"
scan_ssid=1
key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
pairwise=TKIP CCMP
group=CCMP TKIP WEP104 WEP40
psk="phosphor"
}
注意,ssid为路由的名称,phosphor为路由的密码,用户请根据自己的路由密码设置。
将wpa_supplicant.conf文件拷贝到/out/..../system/etc/wifi目录
七:将第一步生成的rt3070sta.ko文件拷贝到/out/..../system/lib/modules目录
八:重新编译android源码,将新生成的uramdisk.img烧录到SD卡:
sudo dd if=/tftpboot/uramdisk.img of=/dev/sdb bs=1M seek=6
将新生成的system.img烧录到SD卡:
sudo dd if=/tftpboot/system.img of=/dev/sdb2
九:重启开发板,进入文件系统后,加载驱动
手动加载驱动如下:
/system/lib/modules # insmod rt3070sta.ko
rt3070sta: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
rt3070sta: Unknown symbol usb_alloc_urb (err 0)
rt3070sta: Unknown symbol usb_free_urb (err 0)
rt3070sta: Unknown symbol usb_alloc_coherent (err 0)
rt3070sta: Unknown symbol usb_register_driver (err 0)
rt3070sta: Unknown symbol usb_put_dev (err 0)
rt3070sta: Unknown symbol usb_get_dev (err 0)
rt3070sta: Unknown symbol usb_submit_urb (err 0)
rt3070sta: Unknown symbol usb_free_coherent (err 0)
rt3070sta: Unknown symbol usb_control_msg (err 0)
insmod: init_module 'rt3070sta.krt3070sta: Unknown symbol usb_deregister (err 0)
rt3070sta: Unknown symbol usb_kill_urb (err 0)
o' failed (No such file or directory)
这是没有添加GPL授权的原因,需要在驱动源码的文件os/linux/usb_main_dev.c文件的开头加上如下一行代码:
MODULE_LICENSE(“GPL”);
然后重新编译、重新加载,即可得到正确的结果。
正常的加载信息如下:
/ # insmod system/lib/modules/rt3070sta.ko
rtusb init rt2870 --->
=== pAd = d4a62000, size = 511440 ===
<-- RTMPAllocTxRxRingMemory, Status=0
<-- RTMPAllocAdapterBlock, Status=0
usbcore: registered new interface driver rt2870
/ #
正常加载后,可以通过下面的命令查询驱动是否正常加载:
cat /proc/net/dev
正常打印如下:
/ # cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
eth0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
usb0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ra0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
/ #
可以看到多了一路ra0了,它就是我们需要的rt2860驱动。
十:配置IP地址,并使能网口
/ # ifconfig ra0 192.168.1.5 up
(Efuse for 3062/3562/3572) Size=0x2d [2d0-2fc]
RTMP_TimerListAdd: add timer obj d4aa9fb0!
RTMP_TimerListAdd: add timer obj d4aa9fe0!
RTMP_TimerListAdd: add timer obj d4aaa010!
RTMP_TimerListAdd: add timer obj d4aa9f80!
RTMP_TimerListAdd: add timer obj d4aa9ef0!
RTMP_TimerListAdd: add timer obj d4aa9f20!
RTMP_TimerListAdd: add timer obj d4a74b24!
RTMP_TimerListAdd: add timer obj d4a63e5c!
RTMP_TimerListAdd: add timer obj d4a63e94!
RTMP_TimerListAdd: add timer obj d4a74bc8!
RTMP_TimerListAdd: add timer obj d4a74ac4!
RTMP_TimerListAdd: add timer obj d4a74b94!
-->RTUSBVenderReset
<--RTUSBVenderReset
Key1Str is Invalid key length(0) or Type(0)
Key2Str is Invalid key length(0) or Type(0)
Key3Str is Invalid key length(0) or Type(0)
Key4Str is Invalid key length(0) or Type(0)
1. Phy Mode = 5
2. Phy Mode = 5
phy mode> Error! The chip does not support 5G band 5!
RTMPSetPhyMode: channel is out of range, use first channel=1
(Efuse for 3062/3562/3572) Size=0x2d [2d0-2fc]
3. Phy Mode = 9
MCS Set = ff 00 00 00 01
<==== rt28xx_init, Status=0
0x1300 = 00064300
/ #
可以查询是否加载正常:
/ # ifconfig ra0
ra0: ip 192.168.1.5 mask 255.255.255.0 flags [up broadcast running multicast]
/ #
十一:将wireless_tools.29移植到android系统
第一步:网上下载wireless_tools源码包,放在/external目录,并解压,这里使用wireless_tools.29.tar.gz
可从下面的网址下载:
http://bbs.9tripod.com/viewthread.php?tid=126&extra=page%3D1
第二步:解压该文件,在external目录中将会新生成wireless_tools.29目录
第三步:在wireless_tools.29目录下创建Android.mk文件,内容如下:
LOCAL_PATH:= $(call my-dir)
################## build iwlib ###################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := iwlib.c
LOCAL_CFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wpointer-arith -Wcast-qual -Winline -MMD -fPIC
LOCAL_MODULE:= libiw
LOCAL_STATIC_LIBRARIES := libcutils libc libm
include $(BUILD_STATIC_LIBRARY)
################## build iwconfig ###################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := iwconfig.c
LOCAL_CFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wpointer-arith -Wcast-qual -Winline -MMD -fPIC
LOCAL_MODULE:= iwconfig
LOCAL_STATIC_LIBRARIES := libcutils libc libm libiw
#LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) # install to system/xbin
#LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
#LOCAL_MODULE_TAGS := eng user
include $(BUILD_EXECUTABLE)
################## build iwlist ###################
include $(CLEAR_VARS)
LOCAL_SRC_FILES := iwlist.c iwlib.h
LOCAL_CFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wpointer-arith -Wcast-qual -Winline -MMD -fPIC
LOCAL_MODULE:= iwlist
LOCAL_STATIC_LIBRARIES := libcutils libc libm libiw
#LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) # install to system/xbin
#LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
#LOCAL_MODULE_TAGS := eng user
include $(BUILD_EXECUTABLE)
第四步:源代码修改
1.将wireless.22.h 更名为wireless.h
2.修改ifrename.c 增加getline的函数,代码可以从external/genext2fs/genext2fs.c中获得
3.修改iwlib.h,将#include <net/ethernet.h>改为#include <net/if_ether.h>
4.在iwlib.h中,将下面的代码移出#ifndef IW_EV_LCP_PK_LEN ...... #endif宏,确保下面的代码生效,否则将提示编译找不到这些宏定义的错误:
struct iw_pk_event
{
__u16 len; /* Real lenght of this stuff */
__u16 cmd; /* Wireless IOCTL */
union iwreq_data u; /* IOCTL fixed payload */
} __attribute__ ((packed));
struct iw_pk_point
{
void __user *pointer; /* Pointer to the data (in user space) */
__u16 length; /* number of fields or size in bytes */
__u16 flags; /* Optional params */
} __attribute__ ((packed));
#define IW_EV_LCP_PK2_LEN (sizeof(struct iw_pk_event) - sizeof(union iwreq_data))
#define IW_EV_POINT_PK2_LEN (IW_EV_LCP_PK2_LEN + sizeof(struct iw_pk_point) - IW_EV_POINT_OFF)
事实上,我们只用将#endif挪在这段代码的上面即可。
第五步:在android源码包根目录下,分别执行如下代码编译文件:
source build/envsetup.sh
mm bionic/libm PRODUCT-imx53_loco-eng
mm external/wireless_tools.29/ PRODUCT-imx53_loco-eng
编译完成,将会在out/target/product/imx53_loco/system/xbin下生成iwlist,iwconfig等无线工具。
第六步:使用adb push或者重新下载system.img映像文件,就可以正常使用wireless_tools了。
使用下面的指令寻找附近的AP:
iwlist ra0 scan
打印如下信息:
/ # iwlist ra0 scan
===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 711
ra0 Scan completed :
Cell 01 - Address: B0:48:7A:51:BA:72
Protocol:802.11b/g/n
ESSID:"armeasy"
Mode:Managed
Frequency:2.412 GHz (Channel 1)
Quality=100/100 Signal level=-43 dBm Noise level=-92 dBm
Encryption key:on
Bit Rates:54 Mb/s
IE: WPA Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: Unknown: DD0E0050F204104A0001101044000102
Cell 02 - Address: 74:EA:3A:1F:6B:FA
Protocol:802.11b/g
ESSID:"szyltf_100"
Mode:Managed
Frequency:2.412 GHz (Channel 1)
Quality=47/100 Signal level=-71 dBm Noise level=-79 dBm
Encryption key:on
Bit Rates:54 Mb/s
IE: WPA Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : CCMP
Pairwise Ciphers (1) : CCMP
Authentication Suites (1) : PSK
Preauthentication Supported
Cell 03 - Address: 94:0C:6D:69:0B:A6
Protocol:802.11b/g
ESSID:"YLTF_100"
Mode:Managed
Frequency:2.412 GHz (Channel 1)
Quality=47/100 Signal level=-71 dBm Noise level=-66 dBm
Encryption key:on
Bit Rates:54 Mb/s
IE: WPA Version 1
Group Cipher : TKIP
Pairwise Ciphers (2) : TKIP CCMP
Authentication Suites (1) : PSK
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : TKIP
Pairwise Ciphers (2) : TKIP CCMP
Authentication Suites (1) : PSK
Preauthentication Supported
Cell 04 - Address: 00:25:86:33:5D:16
Protocol:802.11b/g
ESSID:"TP-LINK_335D16"
Mode:Managed
Frequency:2.437 GHz (Channel 6)
Quality=7/100 Signal level=-87 dBm Noise level=-82 dBm
Encryption key:on
Bit Rates:54 Mb/s
IE: WPA Version 1
Group Cipher : TKIP
Pairwise Ciphers (2) : TKIP CCMP
Authentication Suites (1) : PSK
IE: IEEE 802.11i/WPA2 Version 1
Group Cipher : TKIP
Pairwise Ciphers (2) : TKIP CCMP
Authentication Suites (1) : PSK
Preauthentication Supported
/ #
可见,第一个就是我们需要找的AP。
十二:使用强大的wpa_supplicant连接网络:
/ # wpa_supplicant -Dwext -ira0 -c /system/etc/wifi/wpa_supplicant.conf &
/ # ===>rt_ioctl_giwscan. 4(4) BSS returned, data->length = 635
ioctl[SIOCSIWGENIE]==>rt_ioctl_siwfreq::SIOCSIWFREQ(Channel=1)
: Operation not supported on transport endpoint
/ #
注意,这里的wpa_supplicant一定要用我们自己重新编译出来的文件,如果使用默认的,它是针对atheros的,
将会有前面给出的错误提示,并且反复打印错误信息。
我们可以通过PING路由来测试是否工作正常:
/ # ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes
RTMP_TimerListAdd: add timer obj d4ad873c!
Rcv Wcid(1) AddBAReq
Start Seq = 00000000
RTMP_TimerListAdd: add timer obj d4ada74c!
64 bytes from 192.168.1.1: seq=0 ttl=64 time=89.936 ms
64 bytes from 192.168.1.1: seq=1 ttl=64 time=2.154 ms
64 bytes from 192.168.1.1: seq=2 ttl=64 time=6.433 ms
64 bytes from 192.168.1.1: seq=3 ttl=64 time=0.899 ms
^C
--- 192.168.1.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.899/24.855/89.936 ms
/ #
十三:添加DNS,网关
在没有添加DNS和网关之前,是无法PING通外网的。使用如下命令:
ip route add default via 192.168.1.1
setprop net.dns1 192.168.1.1
设置完后我们PING一下新浪主页,测试是否能正常上网了:
/ # ping 58.63.236.42
PING 58.63.236.42 (58.63.236.42): 56 data bytes
64 bytes from 58.63.236.42: seq=0 ttl=51 time=122.108 ms
64 bytes from 58.63.236.42: seq=1 ttl=51 time=15.205 ms
64 bytes from 58.63.236.42: seq=2 ttl=51 time=7.797 ms
64 bytes from 58.63.236.42: seq=3 ttl=51 time=11.878 ms
^C
--- 58.63.236.42 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 7.797/39.247/122.108 ms
/ #
到此,整个USB WIFI的流程已经走通。由于mx53_qsb开发板没有液晶屏,只能在电脑显示器上显示,而
开发板只有一个USB接口可以当HOST使用,因此USB WIFI接入USB口后,无法用鼠标操作了,所以无法
在UI界面上操作上网流程。这些步骤将在后续有LCD屏后测试,前期WIFI驱动调试到此告一段落。
源码下载请转入如下链接:
http://bbs.9tripod.com/viewthread.php?tid=130&extra=page%3D1