基於Zynq的RT3070 WIFI + hostapd 實現Wifi和WifiAP

之前的博客實現了編譯RT3070的驅動程序實現STA模式和SoftAP模式的wifi,這裏實現另一種方式,貌似是現在比較新的,那兩種也可實現就是略舊。


主機開發環境:ubuntu14.04
交叉編譯器:arm-xilinx-linux-gnueabi-gcc
Linux內核版本:Linux-3.6.0
開發平臺:zynq數字板
作者:zhu


感謝http://blog.csdn.net/zhengnice/article/details/51694474
http://www.07net01.com/2015/07/888012.html兩篇博客爲本次開發提供的寶貴經驗。

1:內核編譯

內核是使用德致倫官方的xilinx內核linux-digilent-master,
github地址:德致倫linux-xilinx-master
我的CSDN下載地址:

內核配置用的之前的配置文件:digilent_zed_1_defconfig,
配置文件
然後參考網上的配置:

[*] Networking support  --->  
        -*-   Wireless  --->
     <*>   cfg80211 - wireless configuration API                        
     [ ]     nl80211 testmode command                                    
     [ ]     enable developer warnings                               
     [ ]     cfg80211 regulatory debugging                             
     [*]     enable powersave by default                             
     [ ]     cfg80211 DebugFS entries                                 
     [*]     cfg80211 wireless extensions compatibility                
     [*]   Wireless extensions sysfs files                               
     {*}   Common routines for IEEE802.11 drivers                          
     [ ]   lib80211 debugging messages                               
     <*>   Generic IEEE 802.11 Networking Stack (mac80211)                 
                  Default rate control algorithm (Minstrel)  --->                 
     [ ]   Enable mac80211 mesh networking (pre-802.11s) support            
     [ ]   Export mac80211 internals in DebugFS                             
     [ ]   Select mac80211 debugging features  ---> 
Device Drivers  --->
       Generic Driver Options  --->
      (/sbin/hotplug) path to uevent helper                                  
      [ ] Maintain a devtmpfs filesystem to mount at /dev                    
      [ ] Select only drivers that don't need compile-time external firmware
      [ ] Prevent firmware from being built  
      -*- Userspace firmware loading support                                
      [*]   Include in-kernel firmware blobs in kernel binary              
      ()    External firmware blobs to build into the kernel binary         
      [ ] Driver Core verbose debug messages                                 
      [ ] Managed device resources verbose debug messages
    [*] Network device support  --->
           [*]   Wireless LAN  --->
               <*>   Ralink driver support  --->
               < >   Ralink rt2500 (USB) support                                    
               < >   Ralink rt2501/rt73 (USB) support                                 
               <*>   Ralink rt27xx/rt28xx/rt30xx (USB) support                      
                 [ ]     rt2800usb - Include support for rt33xx devices                 
                 [ ]     rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)  
                 [ ]     rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)  
                 [ ]     rt2800usb - Include support for unknown (USB) devices          
                 [*]   Ralink debug output

這樣內核配置第一步就實現了STA模式,這裏主要是加載了linux內核源碼裏面的驅動。

2:wifi工具移植

目前可以使用wireless-tools或wpa_supplicant工具來配置無線網絡。但要注意對無線網絡的配置是全局性的,而非針對具體的接口。wpa_supplicant是一個較好的選擇,但缺點是它不支持所有的驅動。另外,wpa_supplicant目前只能連接到那些你已經配置好ESSID的無線網絡。而wireless-tools支持幾乎所有的無線網卡和驅動,但它不能連接到那些只支持WPA的AP。

我兩個都移植了,但調試時wpa_supplicant不怎麼好使,也沒費勁調,就用wireless-tools連接了沒有密碼的路由器。
Wireless tools for Linux是一個Linux命令行工具包,用來設置支持Linux Wireless Extension的無線設備。

下載:wireless_tools.29.tar.gz
wireless-tools
解壓:

#tar zxvf wireless_tools.29.tar.gz
#cd  wireless_tools.29

修改Makefile

ifndef PREFIX
  PREFIX = /home/zhu/my_project/arm/wifi_sta/wifi_lib/wirelesstool/
endif

## Compiler to use (modify this for cross compile).
CC = /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-gcc
## Other tools you need to modify for cross compile (static lib only).
AR = /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-ar
RANLIB = /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-ranlib
#CC = /usr/local/arm/2.95.3/bin/arm-linux-gcc
#AR = /usr/local/arm/2.95.3/bin/arm-linux-ar
#RANLIB = /usr/local/arm/2.95.3/bin/arm-linux-ranlib

編譯:make
將生成的命令工具:iwlist、iwconfig、iwpriv,libiw.so.29 等拷貝到目標板上,路徑爲:分別把他們放到開發板的/bin和/lib目錄下,並賦予權限chmod 777 iw* libiw.so.29

我這裏是在arm上寫了個腳本.sh

ln -s /mnt/wifi_lib/libiw.so.29 /lib/libiw.so.29
ln -s /mnt/wifi_lib/iwconfig /bin/iwconfig
ln -s /mnt/wifi_lib/iwspy /bin/iwspy
ln -s /mnt/wifi_lib/iwevent /bin/iwevent
ln -s /mnt/wifi_lib/iwpriv /bin/iwpriv
ln -s /mnt/wifi_lib/iwlist /bin/iwlist
ln -s /mnt/wifi_lib/iwgetid /bin/iwgetid

因爲我的ramdisk鏡像設置的比較小,copy過去的話空間不夠,就做了個鏈接。效果一樣。

接下來移植openssl
下載:openssl-0.9.8e.tar.gz
解壓後修改Makefile:

INSTALLTOP=/home/zhu/my_project/7Z030/software/wifi_sta/wifi_lib/ssl

# Do not edit this manually. Use Configure --openssldir=DIR do change this!
OPENSSLDIR=/home/zhu/my_project/7Z030/software/wifi_sta/wifi_lib/ssl

CC= /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-gcc
CFLAG= -O
DEPFLAG= -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_GMP -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 
PEX_LIBS= 
EX_LIBS= 
EXE_EXT= 
ARFLAGS= 
AR=/home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-ar $(ARFLAGS) r
RANLIB= /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-ranlib
PERL= /usr/bin/perl
TAR= tar
TARFLAGS= --no-recursion
MAKEDEPPROG=makedepend

編譯:
sudo make & make install 並拷貝libcrypto.a ; libssl.a到開發板的/lib下
同樣做了軟鏈接

ln -s /mnt/wifi_lib/libssl.a /lib/libssl.a
ln -s /mnt/wifi_lib/libcrypto.a /lib/libcrypto.a

因爲沒用wpa_supplicant工具設置wifi,這裏就不表述了,網上編譯wpa_supplicant的文章很多,百度參考下就好了。

3:啓動wifi 連接路由器

這裏先啓動wifi連接路由器,這個版本不使用驅動源碼編譯出的RT3070.STA和.ko了,用linux內核源碼中勾選加rt2870.bin加載完成。

rt2870.bin下載地址:rt2870.bin
也可以到內核網站
git clone git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
把各種固件都下了。

這個文件要複製到板子上的/lib/firmware/中,不然會報錯
這裏寫圖片描述
將下載好的固件 RT2870.bin並放入/lib文件下新創建的firmware目錄中就可以。腳本里:文件系統/lib中沒有firmware目錄,新建一個。

mkdir /lib/firmware
cp /mnt/wifi_lib/rt2870.bin /lib/firmware

這樣開機啓動時運行腳本.sh,就可以ifconfig -a 看到wlan0了,表示wifi的驅動移植完畢。

之後在板子上運行以下命令,或者在啓動腳本里直接運行。

ifconfig wlan0 up
ifconfig wlan0 192.168.1.13
iwconfig wlan0 ESSID TP-LINK_9D9608
#udhcpc -i wlan0 #下面再說這個命令

我的路由器名字時TP-LINK_9D9608,沒有密碼,設置192.168.1.13是wlan0的IP地址,這樣就可以在PC上運行telnet 192.168.1.13登陸arm上的操作系統了。

這裏解決了之前的方式在使用無線時必須將有線網絡禁止
ifconfig eth0 down。這種方式可以同時登陸有線和無線wifi,IP地址不同而已,我的有線和無線連在了一個路由器上,路由器地址192.168.1.1 。

也可以不給wifi設置IP地址,用udhcpc動態隨機獲取IP,這種可以連接外網。
製作文件系統用到了busybox,這裏就有udhcp工具。
從busybox的examples/udhcp/下copy好simple.script文件到開發板/usr/share/udhcpc/下(busybox裏面默認的目錄文件是/usr/share/udhcpc/default.script),並重命名爲default.script.

沒有/share/udhcpc/目錄,新建一個。

mkdir -p /usr/share/udhcpc/
cp /mnt/wifi_lib/default.script /usr/share/udhcpc/

這樣在板子上運行或在腳本里書寫下面命令,就給wifi隨機一個IP。

udhcpc -i wlan0

4:配置wifi+hostapd作爲熱點

首先要對內核配置支持SoftAP參考了下網上的教程對內核做了配置改動,但我的內核編譯好之後,不能啓動,找了好久原因也沒找到。因爲我的內核是支持SoftAP模式的,在之前的博客中編譯的SoftAP源碼之後是可以啓動的,網上的教程改動的太多了,我自己改動了點,最後也成功了。

[*] Networking support  --->
Networking option  ---> 
<*> Packet socket
<*> Unix domain sockets                                         
            < > PF_KEY sockets                                                    
            [*] TCP/IP networking                                        
            [ ]   IP: advanced router                                           
            [*]   IP: kernel level autoconfiguration                                    
            [*]     IP: DHCP support                                               
            [*]     IP: BOOTP support                                               
            [*]     IP: RARP support                                               
            < >   IP: tunneling                                                    
            < >   IP: GRE demultiplexer                                            
            [*]   IP: multicast routing 
[*] Networking support  --->
   <*>   RF switch subsystem support  ---> //注意要選不然在使用hostapd命令時會出錯

配置如果沒有build in RF選項,在使用hostapd命令時會出錯
這裏寫圖片描述

接下來就是工具移植:
I:這裏用了上面移植的openssl.0.9.8e,這裏就不繼續介紹了,參考上面的編譯。

II:移植libnl
下載地址:libnl-1.1.tar.gz

# mkdir install

./configure --prefix=/home/zhuzhu/downloads/libnl-1.1/install(指定安裝路徑)

#  make CC= /home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-gcc

#sudo make install 

將install下的lib文件夾中的libnl.so.1拷貝到開發板/lib目錄下。
在腳本里添加:

ln -s /mnt/wifi_lib/libnl.so.1.1 /lib/libnl.so.1

III:移植Hostapd
下載:hostapd-1.0.tar.gz
解壓後:

# cp defconfig .config
# vim .config

找到這句代碼:去掉註釋。
#CONFIG_DRIVER_NL80211=y

同樣根據你的要求配置其他選項.基本上,只要配置這行就足夠讓hostapd運行WPA/WPA2 驗證和加密。

修改Makefile,分別添加openssl和libnl的頭文件和庫路徑,openssl的路徑和上面不太一樣,我複製到下面目錄了。

CFLAGS += -I/home/zhu/downloads/libnl-1.1/install/include
CFLAGS += -I/home/zhu/coding/openssl-0.9.8e/install/include
LIBS += -L/home/zhu/downloads/libnl-1.1/install/lib
LDFLAGS += -L/home/zhu/downloads/libnl-1.1/install/lib
LIBS += -L/home/zhu/coding/openssl-0.9.8e/install/lib
LDFLAGS += -L/home/zhu/coding/openssl-0.9.8e/install/lib

編譯

# make CC=/home/zhu/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/arm-xilinx-linux-gnueabi-gcc
# sudo make install

將在/usr/local/bin/生成可執行命令hostapd和配置文件hostapd.conf。
這裏不make install 也可以,就在本目錄下找hostapd文件和.conf 。

修改hostapd.conf文件

interface=wlan0
driver=nl80211
ssid=chuhang-1
channel=1
hw_mode=g
ignore_broadcast_ssid=0
auth_algs=1
#wpa=3
#wpa_passphrase=11111111
#wpa_key_mgmt=WPA-PSK   
#wpa_pairwise=TKIP
#rsn_pairwise=CCMP
上面各項解釋如下: 
(1) ssid:無線路由器發射的wifi名稱; 
(2) hw_mode:指定802.11協議,包括 a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g;
========================================================
無線局域網標準 IEEE 802.11協議 
*IEEE 802.11, 1997年,原始標準(2Mbit/s,工作在2.4GHz)。 
*IEEE 802.11a,1999年,物理層補充(54Mbit/s,工作在5GHz)。 
*IEEE 802.11b,1999年,物理層補充(11Mbit/s工作在2.4GHz)。 
*IEEE 802.11g,2003年,物理層補充(54Mbit/s,工作在2.4GHz)。 
使用最多的應該是802.11n標準,工作在2.4GHz頻段,可達600Mbps(理論值) 
========================================================
(3)channel:設定無線頻道;
(4)interface:接入點設備名稱,注意不要包含ap後綴,即如果該設備稱爲wlan0ap,填寫wlan0即可;
(5)driver:設定無線驅動,我這裏是nl80211;
(6)auth_algs=1 
其中auth_algs指定採用哪種認證算法,採用位域(bit fields)方式來制定,其中第一位表示開放系統認證(Open System Authentication, OSA),第二位表示共享密鑰認證(Shared Key Authentication, SKA)。我這裏設置alth_algs的值爲1,表示只採用OSA;
(7)wpa:指定WPA類型,這是一個位域值(bit fields),第一位表示啓用WPA,第二位表示啓用WPA2。在我的配置中,無論設置成1、2或3,都可以正常連接
(8)wpa_passphrase:WPA/WPA2加密需要指定密鑰,這個選項就是配置WPA/WPA2的密鑰。注意wpa_passphrase要求8~63個字符。另外還可以通過配置wpa_psk來制定密鑰,不過要設置一個256位的16進制密鑰,不適合我們的需求;
(9)wpa_pairwise/rsn_pairwise:如果啓用了WPA,需要指定wpa_pairwise;如果啓用了WPA2,需要指定 rsn_pairwise,或者採用wpa_pairwise的設定。

啓動板子,執行

ln -s /mnt/wifi_lib/hostapd /bin/hostapd
ifconfig wlan0 up 
ifconfig wlan0 192.168.0.5
hostapd -B hostapd.conf
#udhcpd /etc/udhcpd.conf #這個下面解釋

在板子上直接執行hostapd -B hostapd.conf 或在腳本里添加即可;如果編譯過程出現錯誤,請自行檢查你的libnl庫和openssl庫是否是使用GCC交叉編譯後可以到ARM板上跑的庫。

這樣就可以作爲熱點了,用電腦連接登陸完全可以,只不過要把PC的IP設成192.168.0.x,纔可以。

使用udhcpd就不用設置PC的IP地址了。和udhcpc相似。

修改busybox/examples/udhcp/udhcpd.conf然後拷貝到開發板/etc目錄下
因爲是實現最基礎的功能,所以我們只要簡單的修改地址池、默認網關以及dns即可,以下是我的配置:

# The start and end of the IP lease block
start       192.168.0.20
end     192.168.0.254

# The interface that udhcpd will use
interface   wlan0

opt dns 192.168.0.1 192.168.0.10
option  subnet  255.255.255.0
opt router  192.168.0.1
#opt    wins    192.168.10.10
#option dns 129.219.13.81   # appended to above DNS servers for a total of 3
option  domain  local
option  lease   864000      # default: 10 days
option  msstaticroutes  10.0.0.0/8 10.127.0.1       # single static route
option  staticroutes    10.0.0.0/8 10.127.0.1, 10.11.12.0/24 10.11.12.1
# Arbitrary option in hex form:
option  0x08    01020304    # option 8: "cookie server IP addr: 1.2.3.4"

運行 就可以啓動dhcp服務器了

cp /mnt/wifi_lib/udhcpd.conf /etc
udhcpd  /etc/udhcpd.conf

這樣就可以使用wifi作爲熱點直接登陸了,並且不用設置IP。至此使用hostapd+udhcpd等工具基於內核mac80211驅動框架就實現了RT3070無線網卡的softAP!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章