Linux开发板中安装WIFI驱动

嵌入式开发板用的是Cubieboard2,linux版本3.4.60+(linux-sunxi3.4),文件系统是debian。WIFI用的是水星USB网卡,型号MW150US。
 
1.Cubieboard2支持的驱动
   首先查了一下Cubieboard2自身支持的wifi驱动,官方系统自带rtl8192cu和bcm4330的驱动,所以只要只这两个芯片的wifi都可以用直接用。其他的需要编译驱动,如 rtl8188,rtl8187 经测编译驱动后可用。
http://www.xshell.net/networks/Cubieboard_Faq.html
 
2.网卡的芯片型号
   网卡没有附带驱动,也没说明书,好在包装盒上写了型号,百度了一下,它采用的芯片是rtl8188eu,ID是8179(一开始看到有的说这个网卡采用的芯片是8188,有的说芯片是8179,关于这个疑惑了半天,后来下面链接中的文章才知道原来8179是ID,代表的就是rtl8188eu芯片。
   把网卡插到设备上,使用#lsusb命令查看系统中的USB设备,结果如下:
#Bus 001 Device 003: ID 0bda:8179 RealtekSemiconductor Corp. 
http://just4fun.cn/?p=650
 
3.下载和编译驱动
   确定了网卡芯片之后就找rtl8188eu芯片的驱动了,从下面这个链接中下载了一个,解压之后打开Makefile。做如下修改:
1 把Cubieboard2对应的平台后面改为”y”。 CONFIG_PLATFORM_ARM_SUN4I = y
2 再到此平台对应的变量区域修改一下内核路径。
KSRC:=/opt/Cubieboard/linux-sunxi
   然后make。但是编译进行了几分钟之后出现了错误,提示:
os_dep/osdep_service.c:1283:21:error:'struct wake_lock' has no member named 'link'
   查看了osdep_service.c源代码,其中没有定义struct wake_lock这个结构体,而它包含的头文件也都是< XXX.h>,没有”XXX.h”的,所以这个结构体定义引起的错误不是这个驱动的源文件造成的,应该是它的#include中用到的头文件造成的。所以这应该是linux内核版本造成的,或者说我所用的这个驱动和linux版本是不匹配的。
驱动链接:http://www.linuxdeepin.com/forum/6/17511
   我又试了一下PC上(在虚拟机中安装的系统是Ubuntu12.04)安装此驱动,把平台修改一下:CONFIG_PLATFORM_I386_PC= y,又出现一堆错误,再看一下链接中的说明,只支持linux3.9以下的版本,我的内核版本是3.11,不过在/lib/modules/下还有一个3.2版本的文件夹(只不过里面只有一个build文件夹)。然后在Makefile的PC平台变量对应的位置修改成这个3.2版本。再次make就通过了,生成了8818eu.ko文件。只不过insmod的时候就出错了(肯定会出错啊,编译得到的驱动版本和正在运行的内核版本不一致嘛,我只不过是想验证下楼主说的支持3.9版本以下的内核)
 
   所以问题又回到“上哪里去找驱动”。又让我找到个,见下面的链接,原来我以前下载的linux-sunxi的drivers/net/wireless下本身就有rtl8818eu的源代码,只不过在menuconfig配置内核的时候,这个不会出现在图形界面上,需要把这整个文件夹拷贝出来,手动编译下。
   编译之前先修改rtl8188eu的Makefile,在文件最开头添加:CONFIG_RTL8188EU=m。另外还是照例修改下平台,和平台对应的变量。
CONFIG_RTL8188EU=m
……
CONFIG_PLATFORM_ARM_SUN4I= y
……
ifeq($(CONFIG_PLATFORM_ARM_SUN4I), y)
KSRC:=/opt/Cubieboard/linux-sunxi
CROSS_COMPILE := arm-linux-gnueabihf-gcc
KVER  := 3.4

……
endif
再次make,这回没有错误生成了8818eu.ko。
http://forum.cubietech.com/forum.php?mod=viewthread&tid=505
 
4.安装驱动
   将刚刚得到的8818eu.ko拷贝到开发板上,#insmod 8818eu.ko,出现以下错误:
#ERR: script_parser_fetch usb_wifi_usbc_numfailed
#ERR: script_parser_fetch usb_wifi_usbc_numfailed
#Error: could not insert module 8188eu.ko:Cannot allocate memory
   这里的usb_wifi_usbc_num表示usbc对应的realtekusb无线芯片的序号。这是因为在script.bin文件(script.bin是被全志SOC内核驱动或LiveSuit使用的针对特定目标板的二进制配置文件,包含如何设置基于A10/A20目标版的各种外设,端口,I/O针脚信息)中缺少了 usb_wifi_para 参数的设置,这时候必须修改script.bin文件,在其中添加以下内容:
[usb_wifi_para]
usb_wifi_used= 1
usb_wifi_usbc_num= 2
   但是script.bin是通过script.fex来生成的,不能直接用文本文档打开script.bin,需要先修改script.fex,用fex2bin工具转换成script.bin。
#cd/opt/Cubieboard/rootfs
#/opt/Cubieboard /sunxi-tools/fex2bin boot/script.fex boot/script.bin
   替换掉开发板中原来的script.bin即可。
http://forum.lemaker.org/cn/thread-87-1-1-.html
 
   再次#insmod 8818eu.ko,出现以下提示,这回终于成功了。
#usbcore: registered new interface driverrtl8188eu
 
5.后续遇到的问题
   之后把整套系统装配起来,USB摄像头和WIFI一起使用,(摄像头以前使用过,一切正常),发生如下错误:
#insmod 8188eu.ko 
8188eu: disagrees about version of symbol module_layout
Error: could not insert module 8188eu.ko: Invalid module format
   猜想可能是内核乱了需要重新编译下吧,反复配置了几次,到最后,连WIFI单独使用也不行了。上面的这个错误貌似挺偏门,遇到的人不多,后来查到这篇解释这个是什么错误的。
1.编译kernel的时候,会生成Module.symvers文件,记录每个Symbol 和相应的CRC code,例如:
0x258d700e raw_seq_open vmlinux EXPORT_SYMBOL_GPL
0xebba1d26 device_add vmlinux EXPORT_SYMBOL_GPL
0xfb0f0e78 device_del vmlinux EXPORT_SYMBOL_GPL
2.编写动态加载module的时候,也会生成类似的文件module_name.mod.c,将module调用到的system call 记录在里面,这个的symbol使用编译module的时候指向的kernel路径。比如这个kernel 版本是2.6.37-2.5。
3.加载这个动态module的时候,kernel会去check加载模块的每一个symbol的CRC,看看是否与kernel相应的symbol相同,不同的话就会报错。同一个kernel版本,不同的config也会出这个问题。
http://blog.sina.com.cn/s/blog_4a471ff601016uyq.html
  我查看了这两个文件,关于module_layout的CRC值果然不一样。那么应该还是内核配置的问题。不过CRC的值的检查问题貌似也不是大问题(看到一些博主说这个主要是用来检测版本的,但是细微的版本区别也造成这个值不匹配,可以关掉这个检测),硬是要用的话,驱动还是可以用的,虽然它提示could not insert module 8188eu.ko,但实际上我#lsmod可以看到驱动已经成功加载的。并且我用一个编写的文件传输的小程序来测试,发现传输可以正常进行。
又配了几次内核,编译了几次8818eu驱动,module_layout的CRC值还是不一样,后来不知怎的,连8818eu的编译也通不过了(我只修改了Makefile呀)。
   后来很偶然的,我把WIFI插着的时候上电,启动信息中竟然打印驱动加载成功了:
usbcore: registered new interface driver rtl8188eu
   可这时候我还没有insmod呢。我又插拔了几次WIFI模块,都能够成功装载。这自动装载的现象,是在编译的时候就直接选择了模块编译的方式,然后安装到指定路径下的驱动才有的表现,可是我make menuconfig中根本没看到这个选项,所以我才把驱动拷贝到/opt下手动insmod的。我到系统的驱动文件路径下去找,果然找到了8188eu.ko。
   这下迷题解开了,第一,首先上面的错误提示的确是内核配置和驱动编译造成的,我中间反复配置过几次,但是并不是每次都重新从driver下拷贝文件重新编译。第二,我首次安装驱动时没有遇到这个错误,那时的内核配置中我没有把这个驱动选上,开发板的驱动文件路径下没有8188eu.ko文件。
 
6. 将驱动直接编译进内核
  把整个驱动的源文件包放到你选定的路径下,例如drivers/net/wireless,找到路径下的Kconfig,在里面添加一行:source "drivers/net/wireless/rtl8188eu/Kconfig"
  那么你使用make menuconfig 时就能看到对应项了,要是你不知道哪个项才是自己的驱动,就打开源文件包的的Kconfig查看下。

你可能感兴趣的:(嵌入式)