用USB无线网卡在新平台全新移植并构建Linux无线网络

2019-07-12 20:36发布

一,构建环境
硬件:Ralink USB无线网卡,
软件:Linux4.12.7,wpa_supplicant , dhcp
在Linux中执行lsusb查看无线网卡vendorId及productId 为 148f:3070
https://wikidevi.com/wiki/List_of_Wi-Fi_Device_IDs_in_Linux LinuxUSB无线适配器设备列表中能够找到,说明内核已经包含了改款无线网卡的驱动; 如下图:
这里写图片描述 (图一) 如果内核没有包含该款网卡驱动,则需要将厂商提供的无线网卡驱动移植到内核中,并添加及选中相应的配置项,让无线网卡驱动编译进内核中; 二,开始构建
下面介绍无线网卡驱动包含在内核中的情况;
- 1,编译内核 从www.kernel.org网站下载4.12.7版本内核,解压,执行make menuconfig针对特定硬件进行配置,或者直接用已经备份好的.config文件进行配置: 针对Ralink USB无线网卡进行配置,首先从上面的图一中可以看到该款网卡的驱动模块为rt2800usb,在源码中搜索该模块名称可以得到配置项为:RT2800USB 在make menuconfig中搜索RT2800USB 得到如下: ``` Symbol: RT2800USB [=n] Type : tristate Prompt: Ralink rt27xx/rt28xx/rt30xx (USB) support Location: -> Device Drivers -> Network device support (NETDEVICES [=y]) -> Wireless LAN (WLAN [=y]) -> Ralink devices (WLAN_VENDOR_RALINK [=y]) (1) -> Ralink driver support (RT2X00 [=n]) Defined at drivers/net/wireless/ralink/rt2x00/Kconfig:137 Depends on: NETDEVICES [=y] && WLAN [=y] && WLAN_VENDOR_RALINK [=y] && RT2X00 [=n] && USB [=y] ``` 根据搜索的结果将RT2800USB配置项依赖的所有配置选中(选择Y),编译进内核: ``` [*] Networking support ---> -*- Wireless ---> <*> cfg80211 - wireless configuration API----------------------------[CFG80211] <*> Generic IEEE 802.11 Networking Stack (mac80211)------------------[MAC80211] Device Drivers ---> [*] Network device support ---> [*] Wireless LAN ---> <*> Ralink driver support ----> <*> Ralink rt27xx/rt28xx/rt30xx (USB) support -----------[RT2800USB] ``` 配置完成后开始编译,make,编译完成后开始安装内核,从启PC或开发板,之后执行ifconfig -a查看网卡设备名称: 如下图: ![这里写图片描述](https://img-blog.csdn.net/20171012130130422?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTM3MjA0ODUxOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 说明内核驱动模块以及配置成功! 注意,如果只执行ifconfig,在网卡还没有开启的情况下,可能什么也看不到;
  • 2,编译无线路由链接工具;
    首先执行ifconfig wlan0 up && ifconfig wlan0 192.168.0.107 配置网卡;配置完成执行ping 192.168.0.1,如下图:
    这里写图片描述 由于还没有链接路由器所以无法ping通; 下载wpa_supplicant源码包并阅读REAMDE及配置文件:
    w1.fi 官网下载 进入wpa_supplicant 页面下载源码包:wpa_supplicant-2.6.tar.gz 最新版本为2.6版本;
    tar xf wpa_supplicant-2.6.tar.gz
    cd wpa_supplicant-2.6/wpa_supplicant 首先阅读README,打开源码wpa_supplicant-2.6/wpa_supplicant目录下的README文件,查看如下部分:
    这里写图片描述 可以看到wpa_supplicant依赖nl80211内核驱动接口及OpenSSL,内核驱动模块已经编译进内核;
    再打开defconfig文件可以看到如下内容:
    这里写图片描述 综上分析,在编译wpa_supplicant之前还需要编译OpenSSL及libnl源码;首先确定这两个库,如果后面编译的时候再缺少别的库,原则就是缺少啥安装啥!
—————————————————————-OpenSSL———————————————————————–
编译OpenSSL:
OpenSSL官网下载最新版本的源码包: openssl-1.1.0f.tar.gz 版本为1.1.0版本;
tar xf openssl-1.1.0f.tar.gz && cd openssl-1.1.0f/
打开INSTALL 阅读如下部分:
这里写图片描述
如果是arm平台则需要配置交叉编译工具,命令为:CC=arm-linux-gcc ./config –prefix=/opt/openssl –openssldir=/usr/local/ssl
注意:CC选项必须在前面,prefix选项可以根据需要更改:此处暂不该; 配置完成之后 make && make install
OpenSSL编译安装完成! ————————————————————-libnl——————————————————————————
编译libnl:
libnl官网 下载源码包: libnl-3.2.25.tar.gz;可以从官网上面的git库 下载更新的版本;
tar xf libnl-3.2.25.tar.gz && cd libnl-3.2.25 这个源码目录没有README及INSTALL文件,可以通过执行./configure –help 查看需要配置的选项,如果是arm平台:需要配置–prefix 及 –host , CC选项;
配置命令为 : ./configure –prefix=$PWD/tmp –host=arm-linux CC=arm-none-linux-gnueabi-gcc
然后编译安装: make && make install libnl 编译安装完成! ——————————————————————wpa_supplicant———————————————————–
接下来在回到wpa_supplicant源码目录:wpa_supplicant-2.6/wpa_supplicant
继续看wpa_supplicant-2.6/wpa_supplicant/README的如下内容:
这里写图片描述 编译之前需要创建.config文件 , 可以看到源码提供了默认的配置文件defconfig , 先将defconfig重命名为.config文件;
然后配置.config,修改如下几个部分: OpenSSL库: # Uncomment following two lines and fix the paths if you have installed OpenSSL # or GnuTLS in non-default location CFLAGS += -I/opt/openssl/include LIBS += -L/opt/openssl/lib libnl库: # driver_nl80211.c requires libnl. If you are compiling it yourself # you may need to point hostapd to your version of libnl. # CFLAGS += -I/opt/netlink/libnl-3.2.25/tmp/include/libnl3/ LIBS += -L/opt/netlink/libnl-3.2.25/tmp/lib/ libnl版本支持: # Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) CONFIG_LIBNL32=y 如果是arm平台,添加如下交叉编译工具选项: CC=arm-none-linux-gnueabi-gcc 开始编译,在编译过程中会出现如下警告和错误:
这里写图片描述
对于警告,搜索”libnl-3.0” 之后发现在 文件 ../src/drivers/drivers.mak 中没有LIBNL_INC宏定义引起这个警告;
修改方法:在.config 文件中定义LIBNL_INC宏: LIBNL_INC=y 对于错误,是由于在链接wpa_passphrase可执行文件的时候找不到crypto动态库引起的;
在Makefile中如下代码中添加打印发现:LIBS_p链接标志并未包含之前制定的OpenSSL的动态库路径; wpa_passphrase: $(OBJS_p) echo $(LIBS_p) #添加该行打印; $(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p) @$(E) " LD " $@ 再在Makefile中查询变量LIBS_p初始化的代码: ifdef LIBS #.config文件还未包含进来,所以LIBS变量还未被定义; # If LIBS is set with some global build system defaults, clone those for # LIBS_c and LIBS_p to cover wpa_passphrase and wpa_cli as well. ifndef LIBS_c LIBS_c := $(LIBS) endif ifndef LIBS_p LIBS_p := $(LIBS) #由于LIBS在.config文件中定义,而.config文件还未包含近来,所以LIBS变量未定义,所以此代码不会执行; endif endif -include .config 通过上述分析,修改方案为:将Makefile中-include .config代码,移动到Makefile第一行即可; -include .config ifndef CC CC=gcc endif 修改完毕,执行make;
查看 Makefile中的install目标发现,安装目录为 : DESTDIR 变量指定,所以之前的prefix并未生效;
安装执行: make DESTDIR=$(pwd)/tmp install 即可; wpa_supplicant,wpa_cli命令编译完成!
如果是arm平台,将上述可执行文件下载到开发板的/sbin/目录即可; ——————————————————————dhcp———————————————————–
编译dhcp:
dhcp官网 下载最新版本dhcp源码包:dhcp-4.3.6.tar.gz 最新版为4.3.6版本;
tar xf dhcp-4.3.6.tar.gz && cd dhcp-4.3.6 打开源码目录下面的README,可以看到如下内容:
这里写图片描述 按照README,执行./configure –help 看看需要配置那些编译选项:
需要配置的选项为:–prefix=$PWD/tmp 安装目录;
–host=arm-linux 如果运行在arm平台,需要配置该选项;
CC=arm-linux-gcc 如果运行在arm平台,需要配置该选项;
综上,配置命令为:./configure –prefix=$PWD/tmp –host=arm-linux CC=arm-linux-gcc
配置过程出现如下错误:
这里写图片描述 根据错误提示,在配置选项中添加–with-randomdev=/dev/random 或 –with-randomdev=no
完善之后的配置命令为:./configure –prefix=$PWD/tmp –host=arm-linux CC=arm-linux-gcc –with-randomdev=/dev/random 配置完成,继续编译 make 出现如下错误:
这里写图片描述 ../bind/lib/libirs.a: could not read symbols: File in wrong format
执行 readelf -h bind/lib/libirs.a 查看该ELF文件的架构信息,如下:
这里写图片描述 为x86架构的文件,说明bind目录配置有问题,查看bind/Makefile,发现:
这里写图片描述 修改bind/Makefile如下: bindconfig = --disable-kqueue --disable-epoll --disable-devpoll --without-openssl --without-libxml2 --enable-exportlib --with-gssapi=no --enable-threads=no --without-lmdb --host=arm-linux --with-randomdev=/dev/random --with-export-includedir=${binddir}/include --with-export-libdir=${binddir}/lib 修改完毕执行make clean && make 继续编译,出现如下错误:
这里写图片描述 还是在bind/Makefile中配置的时候缺少BUILD_CC变量引起,BUILD_CC变量配置的是编译平台的cc或gcc:
修改如下,添加BUILD_CC=gcc: bindconfig = --disable-kqueue --disable-epoll --disable-devpoll --without-openssl --without-libxml2 --enable-exportlib --with-gssapi=no --enable-threads=no --without-lmdb --host=arm-linux --with-randomdev=/dev/random BUILD_CC=gcc --with-export-includedir=${binddir}/include --with-export-libdir=${binddir}/lib 修改完毕,然后make clean && make 继续编译直到完成,执行make install 安装; dhcp工具编译完成! —————————————————————–总结———————————————————–
经过上述步骤的编译,得到如下工具:
wpa_supplicant,wpa_cli,dhclient —————————————————————–使用———————————————————–
wpa_supplicant使用:
阅读wpa_supplicant的README文件的如下部分:
这里写图片描述 可以看到首先将wpa_supplicant放到/bin 目录中,开发板也是该目录;
然后创建/etc/wpa_supplicant.conf配置文件,
最后执行wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B 命令,链接无线热点; 在README的“Configuration file”部分详细介绍了wpa_supplicant.conf文件内容;
在此,使用一种情况:ssid:”tplink” , 认证为 : WAP2; 加密为:PSK;
/etc/wpa_supplicant.conf配置内容如下: # allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=wheel # # home network; allow all valid ciphers network={ ssid="tplink" key_mgmt=WPA-PSK pairwise=CCMP TKIP psk="xxxxxxxx" } 执行wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B dhclient使用:
在README中可以看到如下内容:
这里写图片描述 可见dhclient的所有的使用及配置,都在man page中 ,执行 man dhclient 或 dhclient -h
查询 得到如下用法:
dhclient -cf /etc/dhclient.conf man dhclient.conf
将 man page中的“SAMPLE”部分中提供的实例配置内容,复制到/etc/dhclient.conf中,删除部分内容,修改无线接口,域名服务器,MAC地址;
修改完毕之后的/etc/dhclient.conf内容如下: timeout 60; retry 60; reboot 10; select-timeout 5; initial-interval 2; reject 192.33.137.209; interface "wlan0" { #修改 send dhcp-client-identifier 1:0:a0:24:ab:fb:9c; #修改为自己的MAC地址 send dhcp-lease-time 3600; prepend domain-name-servers 192.168.0.1; #修改 request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, host-name; require subnet-mask, domain-name-servers; script "/sbin/dhclient-script"; media "media 10baseT/UTP", "media 10base2/BNC"; } alias { interface "wlan0"; #修改 fixed-address 192.5.5.213; option subnet-mask 255.255.255.255; } 由上述配置内容可以看到,还需要创建/sbin/dhclient-script脚本; 同上,man dhclient-script
在 man page 的 “FILES” 部分内容可以看到如下内容:
这里写图片描述 可以看出,每一个操作系统有自己的一个dhclient-script脚本,这些脚本放在dhcp源码目录的 client/scripts 目录中,以各个脚本要运行的操作系统名称命名; 综上,创建dhclient-script起始very easy,只需要把源码中操作系统对应的脚本复制一份,重命名为dhclient-script即可;
此处为Linux系统,所以把client/scripts/linux文件 , 放到/sbin目录下,并重命名为dhclient-script即可; 上述工作做完之后,执行dhclient -cf /etc/dhclient.conf命令接口自动分配IP,添加网关及域名解析服务器; —————————————————————–总结———————————————————–
经过上述各个工具使用介绍之后,总结为一下几个命令:
首先执行 wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B 链接热点;
执行 dhclient -cf /etc/dhclient.conf 动态分配IP地址; 执行ifconfig 信息如下:
这里写图片描述 最后执行 ping www.baidu.com 命令即可看到如下信息:
这里写图片描述 至此,在一个全新的平台,全新的无线网卡硬件上面,构建了无线网络环境; —————————————————————–补充———————————————————– 最后,在补充介绍一下wpa_cli命令使用,改名了通过socket IPC和wpa_supplicant之间通信,在上述命令中,需要手动执行
dhclient -cf /etc/dhclient.conf该命令,通过wpa_cli命令可以在无线网卡链接到热点的时候自动执行该命令; 可以在wpa_supplicant源码的README文件中找到使用方法及示例,如下: wpa_cli -a/sbin/wpa_cli_action.sh -B 从README文件中直接复制,wpa_cli_action.sh可执行脚本的内容并修改,如下: #!/bin/sh IFNAME=$1 CMD=$2 if [ "$CMD" = "CONNECTED" ]; then dhclient -cf /etc/dhclient.conf fi if [ "$CMD" = "DISCONNECTED" ]; then fi 最后,只需要执行:
wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -B
wpa_cli -a/sbin/wpa_cli_action.sh -B
这两条命令即可,将这两条命令添加到开机执行脚本中,及 按照热插的配置规则在udev.conf 或 mdev.conf中添加,热插拔的规则如下: <device regex> <uid>:<gid> <permissions> [!] [@|$|*<command>] arm平台的配置可以在busybox源码目录的doc/mdev.txt文件中找到详细的配置说明,此处不再赘述; 经过这样配置之后,在开机或是热插拔之后,无线网卡会自动链接热点,并动态分配IP,建立无线网络环境; 另外,在 dhclient -cf /etc/dhclient.conf 执行该命令,没有成功的时候,可以添加 -d 选项来打印命令的日志,查看具体原因,再分析原因,解决问题; 完结!