小米随身wifi及360随身wifi 使用的都是mt7601u芯片, 是ralink的产品线迭代产品。
2011年被联发科收购后, ralink作为mtk的无线技术事业群。
官网驱动可于https://www.mediatek.com/products/broadbandWifi/mt7601u下载
如果你使用的是Linux v4.2以后的内核, 主线分支里就含有mt7601u的驱动了。
代码路径:
kernel-4.14/drivers/net/wireless/mediatek/mt7601u
mt7601u usb wifi适配器芯片支持两种模式
1). sta, 即station 基站模式, 类似终端设备一样, 可接入无线路由器, 共享热点等。
2). ap, 即access point 无线接入点模式, 跟共享热点类似, 可供其他设备接入, 共享网络。
以下主要介绍下mt7601u sta模式, 在linux平台下的配置过程。
1. 内核编译,
make menuconfig
配置使能mt7601u驱动, 建议编译成内核模块, 利用usb热插拔按需加载。
其他相关依赖如:
mac80211, usb, wlan, netdevices等内核模块也需要使能。
* 注, 由于wifi usb dongle大部分设计的都没有eeprom/flash等存储介质, 所以都是以固件加载的形式运行。
即linux端 将固件利用usb传输给mt7601u端, mt7601u运行该固件。
2. 固件加载
Linux 固件方面有一套框架代码, 可利用request_firmware等函数请求固件。 网上可以找到相关实现原理描述等。
这里简要介绍下:
1). 固件也可采用buildin模式, 或者存放在文件系统中。通常为了避免内核体积过大, 一般不采用buildin模式。
2). 固件存放在/lib/firmware/目录下, 如mt7601u.bin
3). 故固件的加载需要借助用户态的帮助,
4). 此处需要借助uevent, udev来帮忙, 即内核态发出request_firmware请求, 想上发相应的uevent, udev进程处理该请求, 读取默认/指定固件地址, 将firmware加载到内存中, 内核将内存中的固件数据, 通过相应总线发给设备端。 设备端最终加载并运行固件。
由于我这里使用busybox来作为根文件系统。相关的配置如下:
* 使用mdev, 即mini udev来做为用户态udev进程。
mdev需要在启动过程中即执行, 可在inittab或rcS等启动脚本中加入:
[0] mount -t proc proc /proc
[1] mount -t sysfs sysfs /sys
[2] echo /sbin/mdev > /proc/sys/kernel/hotplug
[3] mdev -s
* 内核配置需要开启以下选项:
ONFIG_FW_LOADER=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" (可选, 用户态也可以配置)
COFNIG_FW_LOADER_USER_HELPER (这一项好像不需要, 我没开也加载固件成功了)
3. 内核驱动加载
ok, 正式运行,
/lib/modules/4.14.74-g1cf858c-dirty/kernel/drivers/net/wireless/mediatek/mt7601u # modprobe mt7601u
[ 389.833837] usb 1-1: reset high-speed USB device number 2 using xhci-hcd
[ 390.007620] mt7601u 1-1:1.0: ASIC revision: 76010001 MAC revision: 76010500
[ 390.027804] mt7601u 1-1:1.0: mcu init succeed
[ 390.083861] mt7601u 1-1:1.0: dma init succeed
[ 390.182331] random: fast init done
[ 390.297695] mt7601u 1-1:1.0: Warning: unsupported EEPROM version 0d
[ 390.305794] mt7601u 1-1:1.0: EEPROM ver:0d fae:00
[ 390.316809] mt7601u 1-1:1.0: EEPROM country region 01 (channels 1-13)
[ 390.895839] mt7601u 1-1:1.0: init hardare succeed
[ 391.097014] mt7601u 1-1:1.0: register device succeed
[ 391.227927] usbcore: registered new interface driver mt7601u
4. 查看网卡
/lib/modules/4.14.74-g1cf858c-dirty/kernel/drivers/net/wireless/mediatek/mt7601u # ifconfig -a
******
wlan0 Link encap:Ethernet HWaddr FC:3D:93:B5:AE:36
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 出现, 后续就是相应的网络配置了。
5. iw命令
busybox 自带的网络工具缺少无线部分,
可选择iw命令, linux git上能找到,
https://git.kernel.org/pub/scm/linux/kernel/git/jberg/iw.git
https://wireless.wiki.kernel.org/en/users/documentation/iw
依赖libnl库, 是一个netlink的用户态库, 可在以下网址找到
https://www.infradead.org/~tgr/libnl/
ok, 交叉编译一下。
6. 静态配置
iw命令不支持wpa/wpa2加密模式, 所以我使用自己手机开了个无密码的热点进行测试。
不使用dhcp, dns一类的, 直接静态配置, 流程如下:
/ # iw wlan0 scan
command failed: Network is down (-100)
/ # iw wlan0 link
Not connected.
/ # ifconfig wlan0 up # 开启网口wlan0
/ # iw wlan0 scan # 扫描无线接入点
BSS 5c:c3:07:73:24:4c(on wlan0)
TSF: 47616435 usec (0d, 00:00:47)
freq: 2462
beacon interval: 100 TUs
capability: ESS ShortSlotTime (0x0401)
signal: -67.00 dBm
last seen: 376 ms ago
SSID: river
Supported rates: 1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0
DS Parameter set: channel 11
TIM: DTIM Count 1 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
ERP:
Extended supported rates: 6.0 9.0 12.0 48.0
HT capabilities:
# 比如扫描到我的热点
/ # iw wlan0 connect river # 无密码连接
/ # [ 1657.853698] wlan0: authenticate with 5c:c3:07:73:24:4c
[ 1657.989853] wlan0: send auth to 5c:c3:07:73:24:4c (try 1/3)
[ 1658.057608] wlan0: authenticated
[ 1658.067687] wlan0: associate with 5c:c3:07:73:24:4c (try 1/3)
[ 1658.152893] wlan0: RX AssocResp from 5c:c3:07:73:24:4c (capab=0x401 status=0 aid=1)
[ 1658.275488] wlan0: associated
ok, 连接上手机热点,
由于没有启用dhcp服务, 无法自动分配ip地址, 所以我根据热点网关的ip, 手动配置设备
/ # ifconfig wlan0 192.168.43.111 up
/ # ifconfig
wlan0 Link encap:Ethernet HWaddr FC:3D:93:B5:AE:36
inet addr:192.168.43.111 Bcast:192.168.43.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # ping 192.168.43.127 # ping网关通
PING 192.168.43.127 (192.168.43.127): 56 data bytes
64 bytes from 192.168.43.127: seq=0 ttl=64 time=1054.640 ms
64 bytes from 192.168.43.127: seq=1 ttl=64 time=50.071 ms
64 bytes from 192.168.43.127: seq=2 ttl=64 time=11.817 ms
^C/ # ping 8.8.8.8 # ping 公网dns失败
PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Network is unreachable
ok, ping网关就直接通的。
公网的dns失败, 报错网络不可达。
是的, 默认网关没有配置... 路由不到外网...
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.43.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
/ # route add default gw 192.168.43.127
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.43.127 0.0.0.0 UG 0 0 0 wlan0
192.168.43.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
/ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=246 time=124.220 ms
64 bytes from 8.8.8.8: seq=1 ttl=246 time=31.024 ms
ok, 静态配置很简单, 就两句话.... 配置ip地址(掩码, 广播地址), 配置默认网关...
/ # ifconfig wlan0 192.168.43.111 up
/ # route add default gw 192.168.43.127
然后
/ # ping www.baidu.com
ping: bad address 'www.baidu.com'
/ # ping 180.101.49.12 # ping baidu的ip地址
PING 180.101.49.12 (180.101.49.12): 56 data bytes
64 bytes from 180.101.49.12: seq=0 ttl=48 time=353.789 ms
64 bytes from 180.101.49.12: seq=1 ttl=48 time=27.912 ms
/ # ifconfig lo 127.0.0.1 up
/ # ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: seq=0 ttl=64 time=6.520 ms
64 bytes from 127.0.0.1: seq=1 ttl=64 time=4.074 ms
ping baidu不通, ping baidu ip地址能通, ping localhost能通。 是的, 需要有dns域名服务器, 来做域名和ip地址直接的转换。
当然不需要域名服务器, 如果我们知道目标地址, 本地也可以建立域名和ip转换的规则。
是的, 直接修改/etc/hosts即可,
/etc # cat hosts
127.0.0.1 localhost
180.101.49.12 www.baidu.com
/etc # ping www.baidu.com
PING www.baidu.com (180.101.49.12): 56 data bytes
64 bytes from 180.101.49.12: seq=0 ttl=48 time=237.635 ms
64 bytes from 180.101.49.12: seq=1 ttl=48 time=27.960 ms
64 bytes from 180.101.49.12: seq=2 ttl=48 time=32.283 ms
你看localhost为什么认识, 也是在这个文件当中添加了的。
7. dhcp和dns
ok, 动态ip分配以及域名转换服务后续添加。 先写到这里。