零零碎碎的时间,折腾了好久,看了不知道多少帖子,教程,终于在香蕉派成功编译并加载了小度Wifi的驱动。其实也就是360Wifi,小米Wifi,腾讯Wifi等的驱动。因为它们基本都是mt7601u的芯片。好了,废话不多说,进入主题。
环境
硬件:香蕉派M1/BPI-M1 系统:bananian-1508 网卡:小度Wifi2(mt7601u芯片)
软件
- 编译环境 make等编译环境自然需要准备好。我之前安装了lnmp一键安装包,编译环境都自动给我装好了,所以具体我也不知道需要哪些组件。
- 内核头文件
首先在终端执行
uname -a
,看一下现在系统的内核版本。
然后用nono@pibox ~ % uname -a Linux pibox 3.4.108-bananian #2 SMP PREEMPT Thu Aug 13 06:08:25 UTC 2015 armv7l GNU/Linux
apt-get
命令安装对应版本的内核头文件sudo apt-get install linux-headers-3.4.108-bananian
- 驱动源码
官方的驱动源码下载链接已经失效了,在网上循着文件名
DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2
,找到了一个包,看样子未做太多修改。(这个包应该是新浪微盘下载的) 解压源码包tar -jxvf DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2
- 编译前的准备
编辑源码包下的
common/rtusb_dev_id.c
把上面这段代码修改成下面这段,实际上就是添加上360Wifi、小度Wifi、小米Wifi等的设备ID#ifdef MT7601U {USB_DEVICE(0x148f,0x6370)}, /* Ralink 6370 */ {USB_DEVICE(0x148f,0x7601)}, /* MT 6370 */ {USB_DEVICE(0x2717,0x4106)}, /* Xiaomi Wifi */ #endif /* MT7601U */
如果不确定你的设备ID在不在这上面,可以把你的usb无线网卡连上你的香蕉派,然后终端执行#ifdef MT7601U {USB_DEVICE(0x148f,0x6370)}, /* Ralink 6370 */ {USB_DEVICE(0x148f,0x7601)}, /* MT 6370 */ {USB_DEVICE(0x2717,0x4106)}, /* Xiaomi Wifi */ {USB_DEVICE(0x148f,0x760b)}, /* 360 Wifi */ {USB_DEVICE(0x2a5f,0x1000)}, /* Tencent Wifi */ {USB_DEVICE(0x2955,0x0001)}, /* XiaoDu Wifi */ {USB_DEVICE(0x2955,0x1001)}, /* XiaoDu Wifi */ {USB_DEVICE(0x2955,0x1003)}, /* NuoMi Wifi */ #endif /* MT7601U */
lsusb
命令,根据显示的结果大概推测一下就能找到你的设备ID。如果不确定哪个是usb无线网卡的话,可以先拔掉usb无线网卡,执行lsusb
命令,再插上usb无线网卡,然后执行lsusb
命令。对比两次执行的结果,多出的那一行应该就是了。 比如下面Bus 001 Device 003: ID 2955:1001
这一行,后面没有描述的,就是小度Wifi。万恶的百度啊,改了设备ID就算了,连描述信息也删了。nono@pibox ~ % lsusb Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 002: ID 0bda:8176 Realtek Semiconductor Corp. RTL8188CUS 802.11n WLAN Adapter Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 004: ID 0bc2:ab00 Seagate RSS LLC Bus 001 Device 003: ID 2955:1001 Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
- 编译安装
回到源码主目录,执行
make
,不出意外的话应该能编译成功。 如果编译成功了,就可以执行sudo make install
,把驱动模块安装到系统里去。 接着运行以下命令载入驱动
我也不清楚驱动模块的生效要不要重启系统,然而事实上重启了也不能解决问题。请接着往下看。sudo depmod sudo modprobe mt7601Usta
Debug
重启系统前,我执行了一下sudo ifconfig -a
,查看所有网络设备,然后并没有发现多出的设备。于是,我重启了系统,再次执行该命令,然并卵。
- 发现问题
于是我
dmesg
查看了一下开机信息,找到一点思路。[ 14.243002] Freeing init memory: 228K [ 15.309721] systemd-udevd[159]: starting version 215 [ 15.927477] rtusb init rt2870 ---> [ 15.938697] ===>rt2870_probe()! [ 15.944676] --> RTMPAllocAdapterBlock [ 15.952575] sd 1:0:0:0: Attached scsi generic sg0 type 0 [ 15.974653] === pAd = f02f9000, size = 851128 === [ 15.977963] --> RTMPAllocTxRxRingMemory [ 15.988743] ERROR: 256 KiB atomic DMA coherent pool is too small! [ 15.988752] Please increase it with coherent_pool= kernel parameter! [ 16.022431] <-- ERROR in Alloc Bulk buffer for HTTxContext! [ 16.025672] ---> RTMPFreeTxRxRingMemory [ 16.030100] <--- RTMPFreeTxRxRingMemory [ 16.037726] ERROR!!! Failed to allocate memory - TxRxRing [ 16.066348] <-- RTMPAllocAdapterBlock, Status=3 [ 16.084313] rt2870: probe of 1-1.3:1.0 failed with error -1 [ 16.129699] usbcore: registered new interface driver rt2870
- 解决思路
搜索这些错误代码,顺藤摸瓜,找到了几篇相关的文章。知道了驱动加载失败的原因
ERROR: 256 KiB atomic DMA coherent pool is too small!
。对应的解决方法是在启动代码uEnv.txt
中添加coherent_pool=2M
。然而,bananian-1508
的启动分区(第一个分区)下并没有uEnv.txt
这个文件。仅有的类似的文件是boot.cmd
和boot.scr
。查看了一下boot.cmd
的具体内容,发现跟uEnv.txt
的内容非常相似。(之前我有编辑过uEnv.txt
这个文件。) 下面这是boot.cmd
的具体内容#-------------------------------------------------------------------------------------------------------------------------------- # Boot loader script to boot with different boot methods for old and new kernel # Credits: https://github.com/igorpecovnik - Thank you for this great script! #-------------------------------------------------------------------------------------------------------------------------------- if load mmc 0:1 0x00000000 uImage-next then # mainline kernel >= 4.x #-------------------------------------------------------------------------------------------------------------------------------- setenv bootargs console=ttyS0,115200 console=tty0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait load mmc 0:1 0x49000000 dtb/${fdtfile} load mmc 0:1 0x46000000 uImage-next bootm 0x46000000 - 0x49000000 #-------------------------------------------------------------------------------------------------------------------------------- else # sunxi 3.4.x #-------------------------------------------------------------------------------------------------------------------------------- setenv bootargs console=ttyS0,115200 console=tty0 console=tty1 sunxi_g2d_mem_reserve=0 sunxi_ve_mem_reserve=0 hdmi.audio=EDID:0 disp.screen0_output_mode=EDID:1680x1050p60 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait setenv bootm_boot_mode sec load mmc 0:1 0x43000000 script.bin load mmc 0:1 0x48000000 uImage bootm 0x48000000 #-------------------------------------------------------------------------------------------------------------------------------- fi
- 编辑配置
boot.scr
的内容与上面几乎完全相同,但是文件头部有一部分“乱码”。实际上boot.scr
是由boot.cmd
经过编译得到的。因此可以直接编辑boot.cmd
而不可以编辑boot.scr
。另外,编辑之前一定要备份文件。这都是我血的教训啊。 在boot.cmd
中有两段关于启动参数的配置,保险起见,这两段我们都修改一下。找到setenv bootargs
,在这行代码的最末尾,也就是在rootwait
后面添加参数coherent_pool=2M
。编辑后的代码如下所示#-------------------------------------------------------------------------------------------------------------------------------- # Boot loader script to boot with different boot methods for old and new kernel # Credits: https://github.com/igorpecovnik - Thank you for this great script! #-------------------------------------------------------------------------------------------------------------------------------- if load mmc 0:1 0x00000000 uImage-next then # mainline kernel >= 4.x #-------------------------------------------------------------------------------------------------------------------------------- setenv bootargs console=ttyS0,115200 console=tty0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait coherent_pool=2M load mmc 0:1 0x49000000 dtb/${fdtfile} load mmc 0:1 0x46000000 uImage-next bootm 0x46000000 - 0x49000000 #-------------------------------------------------------------------------------------------------------------------------------- else # sunxi 3.4.x #-------------------------------------------------------------------------------------------------------------------------------- setenv bootargs console=ttyS0,115200 console=tty0 console=tty1 sunxi_g2d_mem_reserve=0 sunxi_ve_mem_reserve=0 hdmi.audio=EDID:0 disp.screen0_output_mode=EDID:1680x1050p60 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait coherent_pool=2M setenv bootm_boot_mode sec load mmc 0:1 0x43000000 script.bin load mmc 0:1 0x48000000 uImage bootm 0x48000000 #-------------------------------------------------------------------------------------------------------------------------------- fi
- 生成配置
boot.cmd
编辑完成,接下来就是要生成boot.scr
文件。这里需要用到u-boot的工具mkimage
,一般都可以直接安装软件源里的u-boot-tools
软件包。或者可以下载u-boot的源代码自己编译。然后就可以用以下命令生成boot.scr
了。当然,要在boot.cmd
的目录下执行。mkimage -A arm -O linux -T script -C none -name 'mt7601usta_debug' -d boot.cmd boot.scr
- 重启生效
这两个文件都有了以后就可以把它们复制到启动分区里了。然后就可以重启了。这一步比较危险,所以要做好文件备份和恢复。
不出意外的话,重启后
dmesg
,可以看到以下信息[ 14.181600] Freeing init memory: 228K [ 15.276835] systemd-udevd[158]: starting version 215 [ 15.916705] rtusb init rt2870 ---> [ 15.918658] ===>rt2870_probe()! [ 15.926758] --> RTMPAllocAdapterBlock [ 15.931477] === pAd = f04b4000, size = 851128 === [ 15.943277] sd 1:0:0:0: Attached scsi generic sg0 type 0 [ 15.945815] --> RTMPAllocTxRxRingMemory [ 15.951554] <-- RTMPAllocTxRxRingMemory, Status=0 [ 15.961370] <-- RTMPAllocAdapterBlock, Status=0 [ 15.962873] NumEndpoints=8 [ 15.965844] BULK IN MaxPacketSize = 512 [ 15.967630] EP address = 0x84 [ 15.970259] BULK IN MaxPacketSize = 512 [ 15.978693] EP address = 0x85 [ 15.981879] BULK OUT MaxPacketSize = 512 [ 15.984206] EP address = 0x 8 [ 15.987348] BULK OUT MaxPacketSize = 512 [ 15.989690] EP address = 0x 4 [ 15.992892] BULK OUT MaxPacketSize = 512 [ 15.995274] EP address = 0x 5 [ 16.000232] BULK OUT MaxPacketSize = 512 [ 16.007318] EP address = 0x 6 [ 16.014121] BULK OUT MaxPacketSize = 512 [ 16.020883] EP address = 0x 7 [ 16.039724] BULK OUT MaxPacketSize = 512 [ 16.051070] EP address = 0x 9 [ 16.058408] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x8 [ 16.069071] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x4 [ 16.078986] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x5 [ 16.114469] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x6 [ 16.136199] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x7 [ 16.143712] RTMP_COM_IoctlHandle():pAd->BulkOutEpAddr=0x9 [ 16.146738] STA Driver version-3.0.0.3 [ 16.153618] -->MT7601_Init(): [ 16.158935] Chip specific bbpRegTbSize=0! [ 16.177183] Chip VCO calibration mode = 0! [ 16.178912] NVM is EFUSE [ 16.181888] Efuse Size=0x1d [Range:1e0-1fc] [ 16.185028] Endpoint(8) is for In-band Command [ 16.187749] Endpoint(4) is for WMM0 AC0 [ 16.190283] Endpoint(5) is for WMM0 AC1 [ 16.192815] Endpoint(6) is for WMM0 AC2 [ 16.195369] Endpoint(7) is for WMM0 AC3 [ 16.197901] Endpoint(9) is for WMM1 AC0 [ 16.200433] Endpoint(84) is for Data-In [ 16.203311] Endpoint(85) is for Command Rsp [ 16.207599] Allocate a net device with private data size=0! [ 16.210633] Allocate net device ops success! [ 16.214475] The name of the new ra interface is ra0... [ 16.216773] RtmpOSNetDevAttach()---> [ 16.220685] <---RtmpOSNetDevAttach(), ret=0 [ 16.224509] <===rt2870_probe()! [ 16.230934] usbcore: registered new interface driver rt2870
- 测试使用
然后可以
sudo ifconfig -a
,看看有没有ra0
这个设备。如果有的话,恭喜你,成功了!这个设备就是你的小度Wifi。然后配置使用方法就跟设备wlan0
一样咯。 执行以下命令可以使ra0设备生效
再执行以下命令,可以扫描无线网络。如果有结果的话,一般来说就正常了。sudo ip link set ra0 up
不知道是不是个bug。第一次扫描时只能扫描到公开网络,第二次扫描时才能显示全部的网络。 按照格式要求配置nono@pibox ~ % sudo iwlist ra0 scan ra0 Scan completed : Cell 01 - Address: 96:74:2A:AC:23:F3 Protocol:11b/g/n BW20 ESSID:"HHUCAN" Mode:Managed Frequency:2.412 GHz (Channel 1) Quality=13/100 Signal level=-85 dBm Noise level=-80 dBm Encryption key:off Bit Rates:65 Mb/s Cell 02 - Address: 96:74:2A:AC:25:D2 Protocol:11b/g/n BW20 ESSID:"HHUCAN" Mode:Managed Frequency:2.412 GHz (Channel 1) Quality=94/100 Signal level=-53 dBm Noise level=-92 dBm Encryption key:off Bit Rates:65 Mb/s Cell 03 - Address: 84:74:2A:AC:25:D2 Protocol:11b/g/n BW20 ESSID:"CMCC-EDU" Mode:Managed Frequency:2.412 GHz (Channel 1) Quality=89/100 Signal level=-55 dBm Noise level=-92 dBm Encryption key:off Bit Rates:65 Mb/s
/etc/wpa_supplicant/wpa_supplicant.conf
,然后执行以下命令测试连接无线网sudo wpa_supplicant -d -Dwext -ira0 -c/etc/wpa_supplicant/wpa_supplicant.conf
进阶
设备名称是ra0
,肯定是有些不习惯。这是有办法修改的。
编辑驱动源码目录下的include/rtmp_def.h
,把下面这段代码
#define INF_MAIN_DEV_NAME "ra"
#define INF_MBSSID_DEV_NAME "ra"
改成
#define INF_MAIN_DEV_NAME "wlan"
#define INF_MBSSID_DEV_NAME "wlan"
然后重新编译,安装,载入驱动就行了。
由于我的香蕉派上原来就有个usb无线网卡,所以新的设备名是wlan1
。随之而来又有了网络配置的问题,重启后我的香蕉派连接不上网络了。幸好第一个usb无线网卡设置了热插拔,把两个网卡都拔掉,然后插上第一个usb无线网卡,就重新连了上来。
网络配置的问题,暂时还没有研究透。于是我使用的设备名依然是ra0
,这样好像没有冲突,重启后两个网卡都能连上网络。