##1.移植wifi驅動需要考慮的問題。 對於ZYNQ開發板來說,移植WIFI驅動需要考慮PL工程的設計、設備樹、linux內核、開發板bootargs參數。 1)首先要檢查vivado工程裏的ZYNQ Processing System是否勾選了USB引腳,否則無法進行後面的移植操作。在這裏,PL工程的PS部分勾選的是USB0,如圖所示。
2)檢查設備樹是否有USB節點,節點對應的參數是否正確。正確是USB節點如下(這個節點是USB0)。
usb@e0002000 {
compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
status = "okay";
dr_mode = "host";
clocks = <0x1 0x1c>;
interrupt-parent = <0x4>;
interrupts = <0x0 0x15 0x4>;
reg = <0xe0002000 0x1000>;
phy_type = "ulpi";
};
可以參考XILINX的配置說明,裏面包含了linux內核和devicetree配置: http://www.wiki.xilinx.com/Zynq+Linux+USB+Device+Driver
3)配置linux內核。
Device Drivers
USB support
<*> Support for Host-side USB
<*> EHCI HCD (USB 2.0) support
<*> USB Mass Storage support
<*> ChipIdea Highspeed Dual Role Controller
<*> ChipIdea host controller
USB Physical Layer drivers --->
<*> Generic ULPI Transceiver Driver
4)最後啓動開發板時使用lsusb命令檢查是否出現下面這些信息:
Bus 001 Device 002: ID 148f:7601
輸出這些信息時就表示成功識別了Ralink Technology, Corp. MT7601U Wireless Adapter ,對於移植WIFI驅動來說,基礎平臺的搭建已經沒有問題了。
##2.驅動移植 說明:因爲我的開發板使用的內核是4.9版本,驅動已經包含在linux kernel裏面,在編譯內核時進行相關的配置就可以了;需要注意的是內核編譯出來的wifi驅動不支持AP模式,AP模式的編譯工作在文章後面介紹。
>Networking support
--- Wireless
<*> cfg80211 - wireless configuration API
[ ] nl80211 testmode command
[ ] enable developer warnings
[ ] cfg80211 certification onus
[*] enable powersave by default
[ ] use statically compiled regulatory rules database
[*] cfg80211 wireless extensions compatibility
<*> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Minstrel
[*] Minstrel 802.11n support
> Device Drivers > Network device support
--- Wireless LAN
[*] MediaTek devices
<M> MediaTek MT7601U (USB) support
[*] Ralink devices
<*> Ralink driver support --->
<*> Ralink rt27xx/rt28xx/rt30xx (USB) support
編譯linux
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j2
編譯modules
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make modules
編譯出來的mt7601u.ko文件在drivers/net/wireless/mediatek/mt7601u下面
把mt7601u.ko復制到開發板備用。 在開發板上啓動linux,執行
insmod mt7601u.ko
在我的開發板上加載成功後顯示這些信息
usb 1-1: reset high-speed USB device number 2 using ci_hdrc
mt7601u 1-1:1.0: ASIC revision: 76010001 MAC revision: 76010500
mt7601u 1-1:1.0: EEPROM ver:0c fae:00
usbcore: registered new interface driver mt7601u
執行 ifconfig -a 命令會看到wlan0設備
當然,這是linux-4.9版本內置的mt7601u驅動,如果使用的版本較低如4.1以下的話就需要自己下載源碼另外編譯驅動了。推薦的源碼下載地址 https://github.com/kuba-moo/mt7601u
如果需要mt7601u.bin文件的話可以到這裏下載 。
##3.移植wireless-tools到開發板 1)首先下載wireless-tools源碼,下載地址在這裏: http://www.linuxfromscratch.org/blfs/view/stable/basicnet/wireless_tools.html
修改Makefile,主要是修改PREFIX, CC, AR, RANLIB這些參數,同時記得把# BUILD_STATIC = y的注釋去掉
##
## Please check the configurion parameters below
##
## Installation directory. By default, go in /usr/local.
## Distributions should probably use /, but they probably know better...
#修改處
ifndef PREFIX
PREFIX = /home/huang/source/wireless/build/wireless-tools
endif
#修改處
## Compiler to use (modify this for cross compile).
CC = /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc
## Other tools you need to modify for cross compile (static lib only).
AR = /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-ar
RANLIB = /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-ranlib
## Uncomment this to build tools using static version of the library.
## Mostly useful for embedded platforms without ldd, or to create
#修改處
## a local version (non-root).
BUILD_STATIC = y
執行 make make install 在wireless-tools/sbin下的文件復制到開發板的/bin目錄下,並且在開發板/bin目錄下執行
chmod 777 iw*
注意:需要復制交叉編譯工具鏈的一些lib文件到開發板的/lib目錄下,否則移植的程式無法運行。
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/libc-2.3.2.so _install/lib
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/libc.* _install/lib
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/libm-2.3.2.so _install/lib
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/libm.* _install/lib
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/ld-* _install/lib
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/libthread_db* _install/lib
##4.配置開發板網路 1)配置wifi適配器,ip地址要和連接的wifi在同一個網域內,如我的wifi熱點地址是192.168.12.1,在開發板設置wlan0設備的地址爲192.168.12.12
ifconfig wlan0 192.168.12.12 netmask 255.255.255.0 up
2)設置默認網關
route add default gw 192.168.12.1
3)掃描wifi網路
iwlist wlan0 scan
掃描完成時顯示如下:
.....
Cell 05 - Address: 90:94:E4:AA:C6:22
Channel:9
Frequency:2.452 GHz (Channel 9)
Quality=57/70 Signal level=-53 dBm
Encryption key:off
ESSID:"Debian"
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s
Bit Rates:24 Mb/s; 36 Mb/s; 48 Mb/s; 54 Mb/s
Mode:Master
Extra:tsf=000005ea01e39533
Extra: Last beacon: 60ms ago
IE: Unknown: 0005646C696E6B
IE: Unknown: 010882848B960C121824
IE: Unknown: 030109
IE: Unknown: 2A0100
IE: Unknown: 32043048606C
.....
4)連接wifi
iwconfig wlan0 essid "Debian"
連接成功後輸出信息
[root@huang:/]#iwconfig wlan0 essid "Debian"
wlan0: authenticate with 74:e5:43:e7:3b:e4
wlan0: send auth to 74:e5:43:e7:3b:e4 (try 1/3)
[root@huang:/]#wlan0: authenticated
mt7601u 1-1:1.0 wlan0: disabling HT as WMM/QoS is not supported by the AP
mt7601u 1-1:1.0 wlan0: disabling VHT as WMM/QoS is not supported by the AP
wlan0: associate with 74:e5:43:e7:3b:e4 (try 1/3)
wlan0: RX AssocResp from 74:e5:43:e7:3b:e4 (capab=0x401 status=0 aid=1)
IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
wlan0: associated
由於是測試用,連接的wifi沒有密碼;有密碼時,假設密碼是1234567890,需要這樣連接
iwconfig wlan0 essid "Debian" key s:1234-5678-90
即每4位爲一組,連接成功後ping一下wifi的地址
[root@huang:/]#ping 192.168.12.1
PING 192.168.12.1 (192.168.12.1): 56 data bytes
64 bytes from 192.168.12.1: seq=0 ttl=64 time=1.713 ms
64 bytes from 192.168.12.1: seq=1 ttl=64 time=1.588 ms
64 bytes from 192.168.12.1: seq=1 ttl=64 time=1.824 ms (DUP!)
64 bytes from 192.168.12.1: seq=2 ttl=64 time=1.523 ms
64 bytes from 192.168.12.1: seq=2 ttl=64 time=2.260 ms (DUP!)
^C
--- 192.168.12.1 ping statistics ---
3 packets transmitted, 3 packets received, 2 duplicates, 0% packet loss
round-trip min/avg/max = 1.523/1.781/2.260 ms
測試一下是否可以連接外網
[root@huang:/]#ping 1.0.0.1
PING 1.0.0.1 (1.0.0.1): 56 data bytes
64 bytes from 1.0.0.1: seq=0 ttl=47 time=164.691 ms
64 bytes from 1.0.0.1: seq=0 ttl=47 time=165.049 ms (DUP!)
64 bytes from 1.0.0.1: seq=1 ttl=47 time=166.982 ms
64 bytes from 1.0.0.1: seq=1 ttl=47 time=167.340 ms (DUP!)
^C
--- 1.0.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 2 duplicates, 0% packet loss
round-trip min/avg/max = 164.691/166.015/167.340 ms
但是如果沒有設置DNS伺服器時,ping域名會ping不通,所以要設置DNS伺服器地址。 1)在/etc/下建立resolv.conf文件,當然也可以從宿主機直接復制過來用。nano /etc/resolv.conf 並在裏面添加:
nameserver 192.168.12.0
nameserver 37.235.1.177
注意:之所以添加192.168.12.0,是因爲執行route命令時看到:
[root@huang:/]#route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 192.168.12.1 0.0.0.0 UG 0 0 0 wlan0
default 192.168.65.1 0.0.0.0 UG 0 0 0 eth0
192.168.12.0 * 255.255.255.0 U 0 0 0 wlan0
192.168.65.0 * 255.255.255.0 U 0 0 0 eth0
wifi相當與一個DNS服務器,所以要添加進來,否則也不能解析域名。
2)從交叉編譯工具鏈添加libnss*文件到根文件系統/lib目錄下
cp -v /opt/Xilinx/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/lib/*nss* _install/lib
重新啓動開發板後就可以正確解析外網域名了。
[root@huang:/]#ping www.bbc.com
PING www.bbc.com (212.58.246.55): 56 data bytes
64 bytes from 212.58.246.55: seq=0 ttl=45 time=335.045 ms
64 bytes from 212.58.246.55: seq=1 ttl=45 time=334.227 ms
64 bytes from 212.58.246.55: seq=1 ttl=45 time=335.225 ms (DUP!)
64 bytes from 212.58.246.55: seq=2 ttl=45 time=335.796 ms
--- www.bbc.com ping statistics ---
4 packets transmitted, 3 packets received, 1 duplicates, 25% packet loss
round-trip min/avg/max = 334.227/335.073/335.796 ms
試一下ipv6
[root@huang:/]#ping6 google.com
PING google.com (2404:6800:4012:1::200e): 56 data bytes
64 bytes from 2404:6800:4012:1::200e: seq=0 ttl=40 time=115.892 ms
64 bytes from 2404:6800:4012:1::200e: seq=1 ttl=40 time=133.562 ms
64 bytes from 2404:6800:4012:1::200e: seq=2 ttl=40 time=153.433 ms
64 bytes from 2404:6800:4012:1::200e: seq=3 ttl=40 time=171.441 ms
--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 115.892/143.582/171.441 ms
也成功了,至此開發板的網絡配置完成。
##5.配置成AP模式
mt7601的AP模式用另外的驅動,上面配置的是STA模式,可以從linux內核直接編譯;但是AP模式要另外下載編譯。mt7601的AP驅動可以從這裏下載:git clone https://github.com/tanaka1892/mt7601u-ap
編譯成功後驅動在mt7601u-ap/os/linux/mt7601Uap.ko,再在/etc下建立wifi/RT2870AP文件夾,把RT2870AP.txt文件複製到此文件夾內。
mkdir -p /etc/wifi/RT2870AP
cp -v RT2870AP.txt /etc/wifi/RT2870AP/
若出現編譯錯誤,如:
/home/huang/xilinx/driver/wifi/mt7601u-ap/os/linux/../../ap/ap_data.c:5213:30:error: passing argument 2 of ‘hex_dump’ from incompatible pointer type [-Werror=incompatible-pointer-types]
hex_dump("DataFrameHeader", pHeader, 36);
則需要修改linux-xlnx-master根目錄下的Makefile文件,在817行處修改
把
816 # enforce correct pointer usage
817 KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
修改爲
816 # enforce correct pointer usage
817 KBUILD_CFLAGS += $(call cc-option,-Wno-error=incompatible-pointer-types)
在我這裏,編譯驅動並且加載成功了,但是後面啓動無線適配器時卻工作不正常,即開啓AP模式後,使用iwconfig查看時,生成了很多個interface,從ra0 - ra15,essid是HT_AP0,HT_AP1…..然而在手機wifi連接界面上只看到了HT_AP0,連接會顯示失敗。 後面我在這個博客 看到了解決辦法,我遇到的問題是驅動沒有成功讀取配置文件,這時候驅動就會使用默認的配置。這時可以修改mt7601u-ap/os/linux/rt_linux.c
int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
{
DBGPRINT(RT_DEBUG_ERROR, ("add: %p %p\n", osfd->f_op, osfd->f_op->read));
/* The object must have a read method */
if (osfd->f_op /*&& osfd->f_op->read*/) {
//return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
return vfs_read(osfd, pDataPtr, readLen, &osfd->f_pos);
} else {
DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
return -1;
}
}
修改保存,重新編譯。在啓動開發板之前,需要在uboot界面修改bootargs參數,比如我的開發板bootargs參數這樣設置
setenv bootargs 'root=/dev/raw rw cma=15M coherent_pool=2M init=/linuxrc'
這裏的啓動方式是q-spi啓動,如果是其他啓動方式則要進行相應修改;注意coherent_pool=2M參數必須要有,否則驅動加載會出錯:
rt2870: probe of 1-1:1.0 failed with error -1
加載成功後使用iwconfig命令可以查看到以下信息。
[root@huang:/home]#iwconfig
lo no wireless extensions.
sit0 no wireless extensions.
eth0 no wireless extensions.
ra0 IEEE 802.11bgn ESSID:"arm-linux-AP"
Mode:Master Channel:11 Access Point: 28:F3:66:71:88:81
Bit Rate=72 Mb/s
使用手機連接成功,AP熱點名是arm-linux-AP。注意:目前僅僅是實現了手機和開發板的局域網通信,由於在AP模式下沒有配置DNS和ip轉發規則,所以並不能訪問外部網路,這個待日後完善。
測試開發板與手機是否連接成功
[root@huang:/home]#ping 192.168.12.104
PING 192.168.12.104 (192.168.12.104): 56 data bytes
64 bytes from 192.168.12.104: seq=0 ttl=64 time=13.620 ms
64 bytes from 192.168.12.104: seq=1 ttl=64 time=232.762 ms
64 bytes from 192.168.12.104: seq=2 ttl=64 time=5.873 ms
64 bytes from 192.168.12.104: seq=3 ttl=64 time=5.972 ms
^C
--- 192.168.12.104 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 5.873/64.556/232.762 ms