目录
一、本季文章将会带来那些干货
1、MT7601网卡驱动的移植
(1)开发环境搭建和确认
ubuntu,开发板内核源码树,linux开发板
(2)源码获取和解压
联发科官方提供了驱动,我们只需移植修改即可。
(3)配置、编译、安装
2、无线网卡的配置和使用
(1)常用无线网卡工具介绍:iwconfig、iwlist、iwpriv、wpa_supplicant
(2)常见WIFI加密格式介绍和路由器端查看:WEP、WPA
(3)wpa_supplicant使用详解
(4)配置本地IP地址、网关、dns等并确认外网连接
3、在自己定制的rootfs中移植USB WIFI
(1)自己定制rootfs
(2)移植wifi驱动并安装
(3)移植iwconfig工具集(LWE)
(4)移植wpa_supplicant
4、在自己定制的rootf中添加dhcp支持
(1)在内核和busybox配置中添加dhcp支持
(2)移植dhcpc和dhcpd并使用
二、项目各项材料的准备和确认
1、开发环境搭建和确认
(1)ubuntu16.04
(2)开发板自带内核的内核源码树
(3)开发板提供的官方linux+QT4.8镜像(我使用的开发板是朱老师物联网大讲堂的开发板study210)
#在uboot命令行设置启动参数
set bootargs console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3
#在uboot命令行将内核从inand中读取到内存DDR中
movi read kernel 30008000
bootm 30008000
(4)ubuntu主机搭建好nfs服务器 和 制作好文件夹形式的rootfs
主机端测试nfs所用:mount -t nfs -o nolock 192.168.1.141:/root/rootfs /opt
ubuntu主机端:sudo /etc/init.d/nfs-kernel-server restart
开发板端:mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 192.168.1.141:/home/rootfs /opt
2、网卡驱动源码确认
DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2
所用资源:
链接:https://pan.baidu.com/s/1v4V7HHoLe8GAD63HQFeO-w
提取码:47ic
--来自百度网盘超级会员V5的分享
将源码下载后,放到ubuntu的一个目录下进行解压,为之后的开发做准备
3、USB WIFI网卡硬件确认
(1)网卡基本信息介绍
详解:https://linux.cn/article-2448-1.html
(2)lsusb命令查看网卡的VID和PID
这是我的(在你哪里查看到的可能会和我的不一样):
Bus 001 Device 005: ID 148f:7601
使用lsusb命令可以显示USB设备的相关信息。
输出信息 信息描述
Bus 001 USB总线编号,001号USB总线编号上只接了一个设备,002总线编号上则接了3个
Device 001 USB设备编号,在一个总线上这个编号是唯一的
ID 1d6b:0002 USB设备的制造商识别码和产品识别码,1d6b是制造商识别码,代表Linux Foundation,0002是产品识别码,代表2.0 root hub
Linux Foundation 制造商的字符串表示形式
2.0 root hub 产品的字符串表示形式
三、驱动源码修改及编译
注意:我们这里需要将usb网卡配置为sta模式(一个可以连接wifi的终端),驱动也是以这种模式进行配置的,而非ap模式(即将开发板作为一个路由器)。
参考阅读:https://blog.csdn.net/knowloveno/article/details/86544768
1、确认USB的VID和PID
(1)进入源码,修改其中的rtusb_dev_id.c文件
#使用以下命令查找我们所需的文件
find -name "rtusb_dev_id.c"
或者
grep -nr "USB_DEVICE_ID rtusb_dev_id" ./
USB_DEVICE_ID rtusb_dev_id[] = {
#ifdef RT6570
{USB_DEVICE(0x148f,0x6570)}, /* Ralink 6570 */
#endif /* RT6570 */
{USB_DEVICE(0x148f, 0x7650)}, /* MT7650 */
#ifdef MT7601U
{USB_DEVICE(0x148f,0x6370)}, /* Ralink 6370 */
{USB_DEVICE(0x148f,0x7601)}, /* MT 6370 */ // 我们的模块就是这个,与上边 lusb 查看的信息符合
#endif /* MT7601U */
{ }/* Terminating entry */
//若是没有我们想要的,则需自己手动添加
};
2、修改源码目录下的Makefile
(1)平台换成:三星
PLATFORM = SMDK
(2)内核源码树路径设置
LINUX_SRC = //linux内核源码树,自己的内核源码路径
(3)交叉工具链路径设置
#(ifeq ($(PLATFORM),SMDK)) 275行
CROSS_COMPILE = //交叉编译环境
这里我给大家提供一份我修改好的Makefile:
链接:https://pan.baidu.com/s/1TrLHGTt395c_SrSOTqHvbA
提取码:pq8h
--来自百度网盘超级会员V5的分享
3、修改网卡名字(可选)
(1)常用无线网卡名称:rax、wlanx
(2)修改源码目录下的include/rtmp_def.h文件
#define INF_MAIN_DEV_NAME "ra"
#define INF_MBSSID_DEV_NAME "ra"
若遇到其他的网卡驱动不在这个目录这个文件,可直接搜索grep “ra” 试试
4、添加 wpa_supplicant 支持
搜索文件:find -name "config.mk"
得到其所在目录:./os/linux/config.mk
确保config.mk文件中:WPA_SUPPLICANT=y
5、编译生成驱动模块
(1)清理&编译
make clean && make -j2
生成os/linux/mt7601Usta.ko就是驱动模块
四、USB WIFI网卡驱动源码简单分析
1、关键点1:把握深度适可而止
(1)使用sourceinsight建立工程,搜索module_init找这个驱动程序的入口。
//os\linux\usb_main_dev.c
INT __init rtusb_init(void)
{
printk("rtusb init %s --->\n", RTMP_DRV_NAME);
return usb_register(&rtusb_driver);//这个函数应该是内核的usb驱动架构提供的
}
/* Deinit driver module */
VOID __exit rtusb_exit(void)
{
usb_deregister(&rtusb_driver);
printk("<--- rtusb exit\n");
}
module_init(rtusb_init);
module_exit(rtusb_exit)
(2)os\linux\usb_main_dev.c 362行,100多行那个是针对2.4版本内核使用的,我们的内核版本是2.6
struct usb_driver rtusb_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
.owner = THIS_MODULE,
#endif
.name=RTMP_DRV_NAME,
.probe=rtusb_probe,
.disconnect=rtusb_disconnect,
.id_table=rtusb_dev_id,
#ifdef CONFIG_PM
#ifdef USB_SUPPORT_SELECTIVE_SUSPEND
.supports_autosuspend = 1,
#endif /* USB_SUPPORT_SELECTIVE_SUSPEND */
suspend: rt2870_suspend,
resume: rt2870_resume,
#endif /* CONFIG_PM */
.supports_autosuspend = 1,
};
(3)有些宏在源码中找不到,并不一定不存在,因为有些宏是在编译过程中(.mk的makefile文件)生成的
可在源码目录下搜索:grep “宏名”
(4)include\rtmp_def.h 1600行开始
#ifdef ANDROID_SUPPORT
#define INF_MAIN_DEV_NAME "wlan"
#define INF_MBSSID_DEV_NAME "wlan"
#else
#define INF_MAIN_DEV_NAME "ra"
#define INF_MBSSID_DEV_NAME "ra"
#endif /* ANDROID_SUPPORT */
#define INF_WDS_DEV_NAME "wds"
#define INF_APCLI_DEV_NAME "apcli"
#define INF_MESH_DEV_NAME "mesh"
#define INF_P2P_DEV_NAME "p2p"
若想知道这些宏如何被使用,在linux中解压的源码目录下使用:grep "宏名" 进行查看
五、WIFI网卡的配置过程
ifconfig -a 查看有哪些网卡
1、iwconfig工具集的介绍和使用演示
(1)linux下专用来配置无线网络的一些命令集
(2)因为iwconfig本身有一定限制,只支持一定的加密格式,在我们这里不用
2、路由器端基础知识
大家可以登录到自己的路由器管理界面,结合学习,登陆的账号、密码可以看看自己的路由器,上边会有标签写了相关内容。
(1)路由器的WAN、LAN
LAN口指的是局域网接口,主要是用于路由器与局域网进行连接。不同的网络设备有不同的接口类型,常见的
局域网接口主要有AUI、SC和RJ-45接口。对使用其上网的设备进行一些设置,否则连接了无法上网。
WAN口指的是广域网接口,主要是用于路由器与广域网进行连接。常见的广域网接口有E1、V.2,路由器自己上
网要进行的设置
(2)无线参数:
SSID:路由器名称
频段:工作通信的频段
模式:设置通信速率
(3)安全类型:WEP和WPA、WPA2
WEP:第一代,与iwconfig工具集结合使用
WPA:可以说是WEP升级版,相对安全
WPA2:WPA的升级版
(4)安全选项
(5)加密算法
AES比TKIP好
(6)PSK密码
就是常说的wifi密码
3、wpa_supplicant配置文件
(1)wpa_supplicant简介
详解:https://blog.csdn.net/qinrenzhi/article/details/80741269
wpa_supplicant是一个应用程序,其是WiFi驱动和用户的中转站外加对协议和加密认证的支持。
它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的,而实际上的工作内容是通过socket(不管是wpa_supplicant与上层还是wpa_supplicant与驱动都采用socket通讯)与驱动交互上报数据给用户,而用户可以通过socket发送命令给wpa_supplicant调动驱动来对WiFi芯片操作它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的,而实际上的工作内容是通过socket(不管是wpa_supplicant与上层还是wpa_supplicant与驱动都采用socket通讯)与驱动交互上报数据给用户,而用户可以通过socket发送命令给wpa_supplicant调动驱动来对WiFi芯片操作
(2)创建/etc/Wireless/RT2870STA/RT2870STA.dat
RT2870STA.dat是驱动源码目录下的自带的一个文件,是这个网卡的配置文件
(3)/etc/wpa_supplicant.conf
是wpa_supplicant这个工具的配置文件。etc目录下本来就有(若无自己创建),不需要创建,修改文件即可,配置这个网卡将来要去连接的路由器的信息
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
network={
key_mgmt=WPA-PSK #加密方式
ssid="JSWK236" #路由器名称
psk="khbycj236" #wifi密码
}
4、网卡配置命令序列
insmod mt7601Usta.ko //安装驱动程序
ifconfig ra0 up //开启无线网卡
wpa_supplicant -B -c /etc/wpa_supplicant.conf -i ra0 //连接无线网络
wpa_cli -i ra0 status //查看连接状态
ifconfig ra0 192.168.1.200 //手动配置ip,同一网段
route add default gw 192.168.1.1 dev ra0 //配置网关
ping 192.168.1.1 //ping 网关(路由器地址)
ping 8.8.8.8 //ping 外网
vi /etc/resolv.conf //配置dns
修改内容:nameserver 192.168.1.1//网关本身就可以做DNS,DNS可以设置多个,当一个不工作时,其他的也可用
ping www.baidu.com //若可ping通外网,则表示成功
注意:
1、ra0的配置和上网前,一定要先关掉eth0(ifconfig eth0 down),否则你ping或者设置
等等都是默认使用的eth0而不是ra0.
2、当我们wifi网卡连接上路由器后,想要ping通路由器(网关),必须本地wifi网卡有一个
和网关同一网段的ip地址才可以。这个本地的ip地址可以dhcp分配,也可以手工配置一个。
3、本地有了ip地址,并且wifi网卡通过wpa_supplicant配置连上路由器后,就能ping通网
关了。但是这时还不能ping通外网,因为本地还没有添加网关配置。添加网关配置有2种方法:
通过route命令动态添加,或者通过/etc/network/interfaces文件添加。
4、添加网关后就能ping通外网IP了,但是还ping不通 www.baidu.com 等域名,因为还没
有dns。
经过上述的操作此时开发板已经可以使用usb无线网卡上网了,下面的内容则是使用不同的方式进行网络管理配置。大家既然看到我的这篇文章,想必大家都是有一定基础的嵌入式Linux开发者,自然懂得下面的操作!
5、使用interfaces文件静态配置
(1)先执行以下命令
insmod mt7601Usta.ko //安装驱动程序
ifconfig ra0 up //开启无线网卡
wpa_supplicant -B -c /etc/wpa_supplicant.conf -i ra0 //连接无线网络
wpa_cli -i ra0 status //查看连接状态
(2)interface文件
第一步,编辑好interface文件,内容如下所示,ra0是我们的wifi网卡的名字,上边提到过在源码可以修改
第二步,使interface文件生效(重启网卡),方法是先ifdown ra0然后ifup ra0
总结:使用/etc/network/interfaces文件其实就是替代了手工配置时的ifconfig分配本地ip地址,和route添加网关这两步。
auth ra0
iface ra0 inet static
address 192.168.1.20
netmask 255.255.255.0
gateway 192.168.1.1
6、使用dhcp动态分配IP
(1)原理:路由器中有个dhcp服务器,本地有dhcp客户端(busybox中提供了)
(2)前导步骤
insmod mt7601Usta.ko //安装驱动程序
ifconfig ra0 up //开启无线网卡
wpa_supplicant -B -c /etc/wpa_supplicant.conf -i ra0 //连接无线网络
wpa_cli -i ra0 status //查看连接状态
(3)当前状态就是:wifi网卡已经启动并且连接上路由器了,但是本地没有ip地址,所以没法ping通路由器。
怎么办?使用dhcp分配一个本地ip。
方法1:命令行使用 udhcpc 命令来分配
udhcpc -i ra0
方法2:使用interface文件选择dhcp模式然后重启网卡
auth ra0
iface ra0 inet dhcp
7、让开发板开机自动连上路由器上网
修改/etc/init.d/rcS及其相关文件
查看S40network以及rcS文件后,根据文件内容。
可创建一个文件S41wifi,内容为:
insmod /home/mt7601/mt7601Usta.ko
ifconfig ra0 up
wpa_supplicant -B -c /etc/wpa_supplicant.conf -i ra0
wpa_cli -i ra0 status
ifdown ra0
ifup ra0
本篇文章是在开发板已有的根文件系统的基础上进行移植的,开发板的根文件系统中自带了wpa_supplicant工具,若是你的开发板没有,需要自己进行移植,具体操作可阅读该小项目的下一篇文章。
注:本文章参考了《朱老师物联网大讲堂笔记》,并结合了自己的实际开发经历以及网上他人的技术文章,综合整理得到。如有侵权,联系删除!水平有限,欢迎各位在评论区交流。