1、网卡选型
首先在网上选择一款usb免驱的wifi网卡,跟卖家确认网卡的VID,PID。
在window下确认usb wifi的PID方法:将usb wifi插入电脑,打开设备管理器,如下图
VID: 0x148F PID:0x3070
在linux中确认usb wifi的VID,PID方法:将usb wifi插入电脑,打开虚拟机,在右下角找到wifi网卡,右键连接
在ubuntu中用命令:lsusb查看usb设备。
VID: 0x148F PID:0x3070
通过PID查看linux内核是否有这款wifI网卡的驱动支持,http://wireless.kernel.org/en/users/Devices/USB搜索
2、驱动移植
2.1、确认linux内核是否有这款usb wifi的驱动(如果没有,则去http://wireless.kernel.org/en/users/Devices/USB搜索并下载驱动)
切换到内核源码wifi驱动目录目录linux3.4.112/drivers/net/wireless,并搜索0x3070。grep “0x3070” * -nR,结果如下:
查看相应目录下的Makefile文件,drivers/net/wireless/rt2x00/Makefile
需要配置上CONFIG_RT2800USB,查看该目录下面的Kconfig文件
config RT2800USB
tristate "Ralink rt27xx/rt28xx/rt30xx (USB) support"
depends on USB
select RT2800_LIB
select RT2X00_LIB_USB
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_CCITT
---help---
This adds support for rt27xx/rt28xx/rt30xx wireless chipset family.
Supported chips: RT2770, RT2870 & RT3070, RT3071 & RT3072
When compiled as a module, this driver will be called "rt2800usb.ko"
可知提示符为: "Ralink rt27xx/rt28xx/rt30xx (USB) support",切换到内核根目录
2.2、切换到内核根目录下,执行make menuconfig,配置内核,支持这款wifi
[*] Networking support --->
-*- Wireless --->
<*> cfg80211 - wireless configuration API
<*> Generic IEEE 802.11 Networking Stack (mac80211)
Library routines --->
{*} CRC-CCITT functions
Device Drivers --->
[*] Network device support --->
[*] Wireless LAN --->
<*> IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)
[*] Support downloading firmware images with Host AP driver
[*] Support for non-volatile firmware download
<M> Ralink driver support --->
<M> Ralink rt27xx/rt28xx/rt30xx (USB) support
注:这里将wifi驱动编译为模块,是为了解决wifi网卡冷启动问题(每次开启启动内核必须拔掉wifi网卡再插上才能工作,可以将模块加入到启动脚本里,挂载文件系统后加载模块)
2.3、make uImage -j2 && make modules,同时将编译好的wifi驱动模块拷贝到nfs文件系统
命令类似如下:
cp * ~/work/nfs/work/driver/wifi/
同时将wifi网卡固件拷贝到根文件系统的/lib/firmware,命令:
cp rt2870.bin ~/work/nfs/lib/firmware/
rt2870.bin:https://pan.baidu.com/s/1awcXpl2jfCsc1TY5sYObgw
2.4、将新内核下载到内存启动,插入usb wifi网卡,使用lsusb查看usb设备
加载wifi驱动模块
#insmod rt2x00lib.ko
#insmod rt2x00usb.ko
#insmod rt2800lib.ko
#insmod rt2800usb.ko
出现如下信息表示网卡识别成功
用ifconfig -a查看网卡信息
#ifconfig -a
可见网卡无ip,还不能上网,需要一直wpa_supplicant,使用 wpa_supplicant提供的命令连接wifi'并上网
3、wpa_supplicant移植
3.1、所需文件
libnl-3.2.23.tar.gz :http://www.infradead.org/~tgr/libnl/files/libnl-3.2.23.tar.gz
openssl-1.0.1d.tar.gz:http://mirrors.ibiblio.org/openssl/source/old/1.0.1/openssl-1.0.1d.tar.gz
wpa_supplicant-2.0.tar.gz:http://w1.fi/releases/wpa_supplicant-2.0.tar.gz
3.2、交叉编译libnl-3.2.23.tar.gz
#tar xzf libnl-3.2.23.tar.gz
#cd libnl-3.2.23/
#./configure --host=arm-linux --prefix=$PWD/tmp
#make
#make install
将编译出的头文件拷贝到交叉编译器默认头文件搜索目录下
#cd tmp/include/libnl3
#cp netlink /home/mark/work/tool/tool_chain/arm-cortex_a8-linux-gnueabi-4.9/lib/gcc/arm-cortex_a8-linux-gnueabi/4.9.4/include
将编译出的库文件拷贝到交叉编译器默认库文件搜索目录下
#cd ../../lib
#cp *so.* /home/mark/work/tool/tool_chain/arm-cortex_a8-linux-gnueabi-4.9/arm-cortex_a8-linux-gnueabi/lib
将编译出的库文件拷贝到根文件系统的lib目录下
#cp *so.* ~/work/nfs/lib/
3.2、交叉编译openssl-1.0.1d.tar.gz
#tar xzf openssl-1.0.1d.tar.gz
#tar xzf openssl-1.0.1d.tar.gz
#cd openssl-1.0.1d/
#./config shared no-asm --prefix=$PWD/tmp
修改Makefile:
CC= arm-linux-gcc
AR= arm-linux-ar $(ARFLAGS) r
RANLIB= arm-linux-ranlib
NM= arm-linux-nm
MAKEDEPPROG= arm-linux-gcc
#make
#make install
将编译出的头文件拷贝到交叉编译器默认头文件搜索目录下
#cd tmp/include/
#cp openssl /home/mark/work/tool/tool_chain/arm-cortex_a8-linux-gnueabi-4.9/lib/gcc/arm-cortex_a8-linux-gnueabi/4.9.4/include
将编译出的库文件拷贝到交叉编译器默认库文件搜索目录下
#cd ../lib
#cp *so.* /home/mark/work/tool/tool_chain/arm-cortex_a8-linux-gnueabi-4.9/arm-cortex_a8-linux-gnueabi/lib
将编译出的库文件拷贝到根文件系统的lib目录下
#cp *so.* ~/work/nfs/lib/
3.3、交叉编译wpa_supplicant-2.0.tar.gz
#tar xzf wpa_supplicant-2.0.tar.gz
#cd wpa_supplicant-2.0/wpa_supplicant/
#cp defconfig .config
修改.config加上一行: CONFIG_LIBNL32=y
修改Makefile:
CC=arm-linux-gcc
#make -j2
#make DESTDIR=$PWD/tmp install
#cd /tmp/usr/local/sbin/
将wpa_cli wpa_passphrase wpa_supplicant拷贝到根文件系统的bin目录
#cp * ~/work/nfs/bin
#find -name "*.conf"
#cp ./wpa_supplicant/examples/plaintext.conf ~/work/nfs/etc/plaintext.conf
4、使用wpa_supplicant
#vim ~/work/nfs/etc/plaintext.conf
# Plaintext (no encryption) network
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="TP-LINK_521" #网络名
psk="9876543219" #密码
}
#mkdir -p /var/run/wpa_supplicant
#wpa_supplicant -B -c/etc/plaintext.conf -iwlan0
查看网络状态
wpa_cli -iwlan0 status
设置ip
#ifconfig wlan0 192.168.1.50
ping路由器
#ping 192.168.1.1
设置DNS和网关
修改/etc/resolv.conf添加DNS:
#nameserver 192.168.1.1
设置网关:
#route add default gw 192.168.1.1
访问外网
#ping www.baidu.com
5、移植DHCP(动态获取ip和自动设置DNS)
dhcp-4.2.5-P1.tar.gz:http://ftp.isc.org/isc/dhcp/4.2.5-P1/dhcp-4.2.5-P1.tar.gz
#tar xzf dhcp-4.2.5-P1.tar.gz
#cd dhcp-4.2.5-P1
#./configure --host=arm-linux ac_cv_file__dev_random=yes
#cd bind
修改Makefile添加:
./configure BUILD_CC=gcc ac_cv_file__dev_random=yes --host=arm-linux --disable-kqueue
#tar xzf bind.tar.gz
#cd bind-9.8.4-P2
修改 lib/export/dns/Makefile.in
gen: ${srcdir}/gen.c
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS}
改为
gen: ${srcdir}/gen.c
${BUILD_CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS}
#cd ../..
#make -j2
#make DESTDIR=$PWD/tmp install
把文件复制到NFS文件系统
#cd /tmp/usr/local
# cp bin/* ~/work/nfs/bin/
# cp sbin/* ~/work/nfs/sbin/
# cp etc/dhclient.conf.example ~/work/nfs/etc/dhclient.conf
#cp etc/dhcpd.conf.example ~/work/nfs/etc/dhcpd.conf
6、使用DHCP动态获取ip
启动内核挂载根文件系统
#wpa_supplicant -B -c/etc/plaintext.conf -iwlan0
##wpa_cli -iwlan0 status
#dhclient -d wlan0
提示无法执行脚本/etc/dhclient-script,没有这个文件
到dhcp-4.2.5-P1源码目录下查看是否有脚本
#cd dhcp-4.2.5-P1/client/scripts/
#ls
#cp linux ~/work/nfs/etc/dhclient-script
修改dhclient-script
#!/bin/bash该为#!/bin/sh,因为嵌入式的shell为bin/sh
#dhclient -d wlan0
会提示无法创建/var/db/dhclient.leases, 此时需要手动创建目录/var/db/
#mkdir -p /var/db
动态获取ip,设置DNS,路由
#dhclient wlan0
#route
#cat /etc/resolv.conf
#ping www.baidu.com
成功访问外网。
7、开机自动连接wifi
利用hotplug热拔插机制,编写mdev.conf配置文件,当网卡加载时自动调用操作wifi的命令
#cd ~/work/nfs
#vim etc/mdev.conf
wlan0 0:0 777 * /sbin/auto_wifi.sh
上面这句话的意思:当加载驱动或者插入网卡时,触发热拔插机制
wlan0 :正则表达式选项,这里直接填写wlan0,嵌入式设备一般只有一个网卡
0:0:用户权限:用户组权限
777:设备文件权限
*:插入设备和删除设备是都执行后面的命令
/sbin/auto_wifi.sh:命令
#vim /sbin/auto_wifi.sh
#!/bin/sh
if [ $ACTION = "add" ];
then
wpa_supplicant -B -c/etc/plaintext.conf -iwlan0
wpa_cli -a/sbin/wpa_action.sh -B
else
killall wpa_supplicant
killall wpa_cli
killall dhclient
fi
$ACTION:mdev机制里的环境变量,当insmod 驱动或者插入usb设备时等于add
上面的脚本意思是插入设备或者加载驱动时执行 wpa_supplicant -B -c/etc/plaintext.conf -iwlan0和wpa_cli -a/sbin/wpa_action.sh -B,卸载模块和拔出usb设备时杀死这三个进程。
wpa_cli -a/sbin/wpa_action.sh -B意思时:当连接上wifi和断开wifi后调用/sbin/wpa_action.sh,类似于回调函数机制
#vim sbin/wpa_action.sh
#!/bin/sh
IFNAME=$1
CMD=$2
if [ "$CMD" = "CONNECTED" ]; then
dhclient $IFNAME
fi
if [ "$CMD" = "DISCONNECTED" ]; then
killall dhclient
fi
IFNAME:网卡名,这里为wlan0
CMD:CONNECTED或者DISCONNECTED
上面的意思是连接上wifi ap时执行dhclient wlan0,动态获取ip,DNS, 网关,断开wifi连接时,删除dhclient进程。