正点原子Linux 移植USB Wifi模块MT7601U驱动(上)
目录
- 下载驱动
- MT7601驱动文件中重要的几个文件
- 1.README_STA_usb
- 2.sta_ate_iwpriv_usage.txt
- 3.config.mk
- 4.Makefile
- 移植过程
- 编译驱动成ko文件
- 复制到根文件系统里
- 驱动加载失败常见原因
- A. DMA缓存大小不够
- B. RT2870STA.dat文件没配置好
- 模块加载测试
- 开启无线网卡并设置IP地址
参考文章 https://blog.csdn.net/rjszcb/article/details/142443415
下载驱动
正点原子出厂适配的USB Wifi模块是RTL8188EUS,这个芯片的的驱动Linux 4.1.15的内核已经自带了,但是MT7601U的驱动要Linux 4.1.19及以后的版本才增加。所以需要手动移植这个驱动,才能正常识别MT7601U这个Wifi模块。
首先要去官网上下载驱动 DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2
解压后有如下文件:
ate common iwpriv_usage.txt Makefile mgmt phy README_STA_usb RT2870STA.dat sta_ate_iwpriv_usage.txt
chips include mac mcu os rate_ctrl RT2870STACard.dat sta tools
MT7601驱动文件中重要的几个文件
MT7601U这个驱动文件涵盖了很多配置选项,除了默认的配置外,还有很多选项可以在驱动文件里设置,如果没有特殊要求选择默认的设计即可。
1.README_STA_usb
这个文件非常重要,解释了整个驱动文件如何使用。这个文件里把自己称为RT2870,可能是MT7601U与RT2870是共用驱动的。
下面这段支持linux 2.4和linux 2.6内核,实测linux 4.1.15内核也可以支持。可能是复制了之前RT2870的13年前的老驱动。
Supporting Kernel:
===================
linux kernel 2.4 and 2.6 series.
Tested in Redhat 7.3 or later.
构建指南这部分是README的核心,要仔细阅读
Build Instructions:
====================
1> $tar -xvzf DPB_RT2870_Linux_STA_x.x.x.x.tgz
go to "./DPB_RT2870_Linux_STA_x.x.x.x" directory.
2> In Makefile
set the "MODE = STA" in Makefile and chose the TARGET to Linux by set "TARGET = LINUX"
define the linux kernel source include file path LINUX_SRC
modify to meet your need.
3> In os/linux/config.mk
define the GCC and LD of the target machine
define the compiler flags CFLAGS
modify to meet your need.
** Build for being controlled by NetworkManager or wpa_supplicant wext functions
Please set 'HAS_WPA_SUPPLICANT=y' and 'HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y'.
=> #>cd wpa_supplicant-x.x
=> #>./wpa_supplicant -Dwext -ira0 -c wpa_supplicant.conf -d
** Build for being controlled by WpaSupplicant with Ralink Driver
Please set 'HAS_WPA_SUPPLICANT=y' and 'HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n'.
=> #>cd wpa_supplicant-0.5.7
=> #>./wpa_supplicant -Dralink -ira0 -c wpa_supplicant.conf -d
4> $make
# compile driver source code
# To fix "error: too few arguments to function ˉiwe_stream_add_event"
=> $patch -i os/linux/sta_ioctl.c.patch os/linux/sta_ioctl.c
5> $cp RT2870STA.dat /etc/Wireless/RT2870STA/RT2870STA.dat
6> load driver, go to "os/linux/" directory.
#[kernel 2.4]
# $/sbin/insmod rt2870sta.o
# $/sbin/ifconfig ra0 inet YOUR_IP up
#[kernel 2.6]
# $/sbin/insmod rt2870sta.ko
# $/sbin/ifconfig ra0 inet YOUR_IP up
7> unload driver
$/sbin/ifconfig ra0 down
$/sbin/rmmod rt2870sta
- 先解压文件;
- 设置Makefile 里的MODE = STA(就是设置为站点模式),TARGET = LINUX(设置为LINUX编译),然后把LINUX_SRC改为自己要编译的内核目录。
- 设置config.mk里GCC和LD用的交叉编译器,也就是在Makefile里配置CROSS_COMPILE为自己用的交叉编译器。CFLAGS是一个一个环境变量用于指定在编译 C 语言源代码时传递给编译器的选项或标志,比如优化级别、调试信息的生成、预处理器宏的定义等。
如果要驱动程序被 NetworkManager 或 wpa_supplicant 的 wext 函数控制,需要设置宏(HAS_WPA_SUPPLICANT=y 和 HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y) - 编译程序时,如果有错误提示iwe_stream_add_event函数在调用时提供的参数太少,就要用"=> $patch -i os/linux/sta_ioctl.c.patch os/linux/sta_ioctl.c"这条命令来打个补丁。-i选项告诉patch命令要应用的补丁文件的名称。
- 把RT2870STA.dat复制到根目录底下的/etc/Wireless/RT2870STA/RT2870STA.dat
- 编译完成的modules文件在os/linux/这个目录下。
2.sta_ate_iwpriv_usage.txt
这个文件是iwpriv命令的介绍,但开头就提醒:如果您不熟悉硬件知识,建议不要随意修改硬件的默认值。因为不当的修改可能会导致硬件损坏或系统不稳定。
ATE Test Command Format for station driver
****** IMPORTANT ******
If you are not familiar with hardware, it is recommanded not to modify hardware default value.
It may damage hardware.
3.config.mk
这个文件下主要是配置项,我暂时保持全部默认
4.Makefile
Makefile别看文件很长,其实是把各种配置都写进去了,如果按默认配置来,可以浓缩成下面这样:
# 配置Wifi模式、Target、Chipset和OSABL
WIFI_MODE = STA
TARGET = LINUX
CHIPSET = MT7601U
OSABL = NO
# 提取Chipset中的MODULE信息
MODULE = $(word 1, $(CHIPSET))
# RT28xx目录
RT28xx_DIR = $(shell pwd)
# 包含Linux配置
include $(RT28xx_DIR)/os/linux/config.mk
# 源码目录
RTMP_SRC_DIR = $(RT28xx_DIR)/RT$(MODULE)
# 导出变量
export WIFI_MODE RT28xx_DIR RT28xx_MODE LINUX_SRC CROSS_COMPILE CROSS_COMPILE_INCLUDE PLATFORM RELEASE CHIPSET MODULE RTMP_SRC_DIR TARGET HAS_WOW_SUPPORT OSABL
# 定义phony目标
.PHONY: all build_tools clean
# 构建目标
all: build_tools $(TARGET)
# 构建工具
build_tools:
$(MAKE) -C tools
$(RT28xx_DIR)/tools/bin2h
# Linux目标
LINUX:
cp -f os/linux/Makefile.6 $(RT28xx_DIR)/os/linux/Makefile
$(MAKE) -C $(RT28xx_DIR)/os/linux/
# 清理目标
clean:
ifeq ($(TARGET), LINUX)
cp -f os/linux/Makefile.clean os/linux/Makefile
$(MAKE) -C os/linux clean
rm -rf os/linux/Makefile
endif
这一句 $(MAKE) -C $(RT28xx_DIR)/os/linux/ 表明最后的编译其实是编译os/linux/ 下的Makefile文件。
打开os/linux/Makefile才能看到具体的编译过程:
include $(RT28xx_DIR)/os/linux/config.mk
obj_wsc :=
obj_vht :=
obj_cmm := \
../../common/crypt_md5.o\
../../common/crypt_sha2.o\
../../common/crypt_hmac.o\
../../common/crypt_aes.o\
../../common/crypt_arc4.o\
../../common/mlme.o\
# 后面还有很长,不列举
最终的Makefile会调用config.mk里的配置项,然后根据配置选择要加载的文件进行编译。
移植过程
获取USB Wifi的厂商ID和产品ID,插入MT7601U后有如下显示:
[ 259.833929] usb 1-1.1: New USB device found, idVendor=148f, idProduct=7601
[ 259.840211] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 259.847456] usb 1-1.1: Product: 802.11 n WLAN
[ 259.852241] usb 1-1.1: Manufacturer: MediaTek
[ 259.856163] usb 1-1.1: SerialNumber: 1.0
通过lsusb也能查看到:
Bus 001 Device 003: ID 148f:7601
厂商ID为148f,产品ID为7601,这个后面会用到。
1.修改DPO_MT7601U_LinuxSTA_3.0.0.4_20130913/common/rtusb_dev_id.c存放的是USB设备的ID信息,可以看到已经定义了MT7601U的厂商ID和设备ID。
2.修改主目录底下的Makefile文件,原来的驱动PLATFORM = PC,需要注释掉改为PLATFORM = SMDK,SMDK是三星的Linux开发板,正点原子Linux开发板和这个最接近。
#PLATFORM: Target platform
PLATFORM = PC
#PLATFORM = 5VT
#PLATFORM = IKANOS_V160
#PLATFORM = IKANOS_V180
#PLATFORM = SIGMA
#PLATFORM = SIGMA_8622
#PLATFORM = INIC
#PLATFORM = STAR
#PLATFORM = IXP
#PLATFORM = INF_TWINPASS
#PLATFORM = INF_DANUBE
#PLATFORM = INF_AR9
#PLATFORM = INF_VR9
#PLATFORM = BRCM_6358
#PLATFORM = INF_AMAZON_SE
#PLATFORM = CAVM_OCTEON
#PLATFORM = CMPC
#PLATFORM = RALINK_2880
#PLATFORM = RALINK_3052
#PLATFORM = SMDK
...
3.继续修改Makefile
ifeq ($(PLATFORM),SMDK)
LINUX_SRC = /home/alientek/linux/gitstore/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
CROSS_COMPILE = arm-linux-gnueabihf-
endif
4.修改DPO_MT7601U_LinuxSTA_3.0.0.4_20130913/include/rtmp_def.h,把无线网名称从ra改为wlan
#define INF_MAIN_DEV_NAME "wlan"
#define INF_MBSSID_DEV_NAME "wlan"
5.修改config.mk,添加wpa_supplicant支持,“HAS_WPA_SUPPLICANT=y”。
编译驱动成ko文件
编程后的 mt7601Usta.ko 文件在/os/linux/目录下
复制到根文件系统里
mt7601Usta.ko复制到开发板根目录的/lib/modules/4.1.15/里,
RT2870STA.dat复制到/etc/Wireless/RT2870STA/里。
然后insmod 或者 modprobe mt7601Usta.ko
驱动加载失败常见原因
A. DMA缓存大小不够
因为linux 的DMA块设置的太小加载失败。
有两种方法,一种是改bootloader里的参数,增加coherent_pool=2M,如下:
setenv bootargs 'console=ttymxc4,115200 coherent_pool=2M root=/dev/mmcblk1p2 rootwait rw'
另一种是改内核,修改内核里的dma-mapping.c文件
改为
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M
改其他大小也可以,在这个文件里找一个合适的大小
B. RT2870STA.dat文件没配置好
如果出现 rt28xx_open return fail! 表明配置文件没设置好,重新拷贝DPO_MT7601U_LinuxSTA_3.0.0.4_20130913/etc/Wireless/RT2870STA/RT2870STA.dat这个文件到/etc/Wireless/RT2870STA/中
模块加载测试
如果使用过depmod命令,会在/lib/modules/4.1.15/ 下产生这样一个文件 modules.alias。
alias usb:v148Fp760Bd*dc*dsc*dp*ic*isc*ip*in* mt7601Usta
alias usb:v148Fp7601d*dc*dsc*dp*ic*isc*ip*in* mt7601Usta
alias usb:v148Fp6370d*dc*dsc*dp*ic*isc*ip*in* mt7601Usta
alias usb:v148Fp7650d*dc*dsc*dp*ic*isc*ip*in* mt7601Usta
这个格式为 usb:v<vendor_id>p<product_id>ddcdscdpiciscipin <module_name>,只要检查到usb有对应vendor_id和对应product_id的USB设备插入,就会自动调用<module_name>,也就是wifi 模块mt7601Usta.ko
开启无线网卡并设置IP地址
-
使用命令“ifconfig wlan0 up”开启无线网卡
-
然后在/etc/wpa_supplicant.conf文件里配置要连接的wifi账号和密码。
-
最后使用wpa_supplicant -D wext -c /etc/wpa_supplicant.conf -i wlan0 &或 wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf & 运行区别在于wext和nl80211。-D wext中的wext代表“Wireless Extensions”(无线扩展)。这是Linux内核中一套用于支持无线LAN设备的API集合。wext是较老的无线驱动接口,它提供了一套标准的接口用于配置和控制无线设备,包括扫描可用的网络、连接到网络、设置加密等。
然而随着Linux内核的发展,更现代和更强大的接口如nl80211(通过-D nl80211指定)已经成为主流。nl80211是Linux内核中用于无线网络的新API,它提供了更丰富的功能和更好的性能。如果无线驱动支持nl80211,可以尝试改成nl80211,如果运行起来有问题改回wext。 -
出现CTRL-EVENT-CONNECTED后表示连接成功。