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
0×1300 = 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通外網的。使用如下命令:
busybox 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驅動調試到此告一段落。