当时在采集RPi的配件时,是依据elinux.org上RPi_VerifiedPeripherals的信息。上面所列出的可兼容硬件都是RPi玩家亲试的。选择TP-LINK TL-WN725N USB无线网卡的原因就是上面写着“TL-WN725N Works out of the box on Raspbian 2012-12-16 without a powered USB hub.”。当时也有考虑过EDUP N8508,但因为它需要接上有源USB HUB来保证供电,而我不想在用作无线路由时还要带着一个USB HUB,所以就选择了TL-WN725N。 但买回来的TL-WN725N插入到RPi却无法驱动。ifconfig -a没有看到wlan0。无论是在Raspbian还是Arch Linux ARM下都无法使用。 的显示是: - Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. LAN9500 Ethernet 10/100 Adapter
- Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
- Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
- Bus 001 Device 004: ID 0bda:8179 Realtek Semiconductor Corp.
复制代码和网上一些论坛里贴出的不一样: - Bus 001 Device 008: ID 0bda:8176 Realtek Semiconductor Corp. RTL8192CU 802.11n WLAN Adapter
复制代码连具体的芯片型号也没识别出来。也在论坛问一下,有人说是供电的问题。但我也试过插到有源的USB HUB里,lsusb得到的结果一样。不过,发现一个问题是网上贴出的lsusb结果中的USB ID和我的不一样,网上的是8176,而我的是8179。于是google一下才发现,这个型号的网卡分v1和v2,v1(即8176)的芯片是8192cu,而v2(即8179)的芯片是8188eu。于是到Realtek的官网找了一下,没有8188eu。但感觉TL-WN725N两个版本的芯片应该是差不多,否则厂家不可能这样替换,而价格和功能的说明却没改。所以就下了Realtek官网上8192cu的驱动下来编译试试。结果不行,ifconfig -a和lsusb显示的结果一样,而lsmod中却能看到新编译的8192cu驱动已经被内核加载了,而旧的rtl8192cu也被禁止了。在苦恼之际,随便看了一下8192cu驱动中的文档,却发现有提到RTL8188eu,但在驱动的发行说明中的支持芯片列表中却没看到RTL8188eu。难道是官方还没有提供8188eu的Linux驱动,而google“8188eu linux driver”之后发现有很多8188eu的Windows驱动,却没有Linux的。而在某论坛中发现有人也是用v2版的,而他在一个国产的Android智能电视棒的Linux系统源码中找到了8188eu的驱动代码:https://github.com/Red54/linux-shumeipai2/tree/sunxi-3.0/drivers/net/wireless/rtl8188eu。看了一下其github中的提交备注和对比了一下它和8188cu的源码,发现这个驱动源码应该是在8192cu的基础上修改的,而不是官方发布的。不过管不了那么多了,下载下来试试。 由于在编译安装驱动的过程,要用到gcc编译工具链,还有一些Linux的实用工具和用unzip解压驱动源码包,所以先要通过pacman安装它们: - [root@alarmpi ~]# pacman -S util-linux unzip base-devel
复制代码安装好上述的软件包后,最好重新启动一下系统: 在编译之前,需要修改驱动源码目录里Makefile文件中的编译选项。在Makefile里可以找到如下的目标编译平台开关宏。可见其中的默认配置是i386平台: - ...
- CONFIG_PLATFORM_I386_PC = y
- CONFIG_PLATFORM_ANDROID_X86 = n
- CONFIG_PLATFORM_ARM_S3C2K4 = n
- CONFIG_PLATFORM_ARM_PXA2XX = n
- ...
复制代码这里没有RPi的BCM2708平台配置,所以需要自行添加。首先在将CONFIG_PLATFORM_I386_PC改为n,并在下面添加RPi的目标编译平台开关宏,修改后的代码如下: - ...
- CONFIG_PLATFORM_I386_PC = n
- CONFIG_PLATFORM_BCM2708 = y
- CONFIG_PLATFORM_ANDROID_X86 = n
- CONFIG_PLATFORM_ARM_S3C2K4 = n
- CONFIG_PLATFORM_ARM_PXA2XX = n
- ...
复制代码接下来是创建新增的目标编译平台配置项。还是在Makefile里,继续往下找,可以看到: - ...
- ifeq ($(CONFIG_PLATFORM_I386_PC), y)
- EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
- SUBARCH := $(shell uname -m | sed -e s/i.86/i386/)
- ARCH ?= $(SUBARCH)
- CROSS_COMPILE ?=
- KVER := $(shell uname -r)
- KSRC := /lib/modules/$(KVER)/build
- MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/
- INSTALL_PREFIX :=
- endif
- ifeq ($(CONFIG_PLATFORM_TI_AM3517), y)
- EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_SHUTTLE
- CROSS_COMPILE := arm-eabi-
- KSRC := $(shell pwd)/../../../Android/kernel
- ARCH := arm
- endif
- ...
复制代码在ifeq ($(CONFIG_PLATFORM_I386_PC), y)...endif和ifeq ($(CONFIG_PLATFORM_TI_AM3517), y)之间添加CONFIG_PLATFORM_BCM2708的编译配置参数,即添加如下的代码: - ...
- ifeq ($(CONFIG_PLATFORM_BCM2708), y)
- EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
- ARCH := arm
- CROSS_COMPILE :=
- KVER := $(shell uname -r)
- KSRC := /lib/modules/$(KVER)/build
- MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless
- INSTALL_PREFIX :=
- MODULE_NAME := 8188eu
- endif
- ...
复制代码解释一下这些编译参数的含意: - EXTRA_CFLAGS:附加编译选项,可用值如下:
- CONFIG_BIG_ENDIAN和CONFIG_LITTLE_ENDIAN是大端存储械和小端存储模式。两种存储模式在ARM上都支持,而默认是小端存储,所以这里选择了CONFIG_LITTLE_ENDIAN
- CONFIG_MINIMAL_MEMORY_USAGE是指定以小内存分配模式。为了在性能较强的平台上获得较好的性能,驱动会分配大尺寸的连续内存空间作为TX/RX的IO缓冲区。这种分配模式在嵌入式平台中可能导致内存分配失败,可以通过定义此项来避免这个问题。考虑到RPi的内存比较大,所以不使用小内存分配模式,故此项忽略
- CONFIG_PLATFORM_ANDROID是用在没有定义CONFIG_ANDROID宏的旧版本Android平台上强制生成Android代码的情况
- ARCH:目标编译平台。RPi的BCM2853是ARM架构,填“arm”
- CROSS_COMPILE:指定交叉编译工具链。直接在RPi上编译,不需要指定此项
- KVER:内核版本。通过shell的uname -r获取即可
- KSRC:内核源代码路径。填/lib/modules/$(KVER)/build
- MODDESTDIR:模块目标目录。这个选项是用于指定编译好的驱动模块的安装路径,填/lib/modules/$(KVER)/kernel/drivers/net/wireless。其实也可以不填此项,等编译完成后将编译好的.ko文件复制到指定的目录也可以,并使用depmod -a命令将编译好的驱动模块安装到内核中
- INSTALL_PREFIX:模块安装目录。这个可以不填,但如果编译出现的模块有多个文件,也可以设置专门的目录用于存放。如果填写了此项,那些模块的安装目录就会变成:MODDESTDIR/INSTALL_PREFIX,而不是MODDESTDIR了
- MODULE_NAME:模块名称。最后编译出来的驱动文件的名称就是此名称加.ko。如果没有设置此项,则默认为8188cu,即编译好的驱动文件名称为8188eu.ko
把上述的内容都修改好后,保存Makefile文件,就可以用 - [root@alarmpi rtl8188eu]# make && make install
复制代码来编译及安装驱动模块。
由于模块没有编译进内核中,而是作为附加模块来编译的,所以要让系统在启动的时候自动加载它才可以使用。这里使用systemd的方法来设置,在/etc/modules-load.d目录下创建一下模块加载的配置文件(如8188eu.conf),在配置文件里写入驱动文件的名称,但不要带.ko,如8188eu即可。
所有这些完成后,重新启动系统就可以使用TL-WN725N了。lsusb依然没有显示其芯片型号,不过ifconfig -a可以看到wlan0了。
正在兴奋之余,安装了hostap: - [root@alarmpi ~]# pacman -S hostap
复制代码,配置好/etc/hostapd/hostapd.conf,却提示nl80211驱动不兼容此网卡。弄了几天才找到可用的驱动,好不容易才让系统识别到无线网卡,现在又冒出一个问题。再一次绝望了!
在绝望之余,突然在8192cu的官方驱动包时看到有一个关于软ap的使用文档,便好奇地打开看看。发现里面关于启动软ap的步骤中的第5步是编译驱动包里的一个hostap工具。然后翻了翻其他pdf文档,在一个关于软ap模式特性的文档里讲到,托管网络模式需要hostap加上基于Realtek专用的871x驱动接口才可以启动。一下子豁然开朗了!原来这个系列的无线网卡不再使用老试的nl80211兼容驱动来打开软ap模式,而是需要Realtek专用的驱动来实现的。
于是,解压8192cu官方驱动包中的wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_rtw_20120803.zip,切换到其中的hostapd目录,执行make进行编译。完成后用编译好的hostapd覆盖掉/usr/bin/hostapd,再将/etc/hostapd/hostapd.conf里的driver项改为rtl871xdrv,通过 - [root@alarmpi ~]# hostapd /etc/hostapd/hostapd.conf
复制代码启动软ap。
用手机搜索一下,找到刚启动的软ap了。
在上面提到的软ap模式特性文档中说明了这个专用的ap驱动只支持CCMP安全模式和WPA-PSK认证模式,所以在/etc/hostapd/hostapd.conf中最好将wpa_key_mgmt设置为WPS-PSK,和将wpa_pairwise设置为CCMP。其他的配置参数请见具体的说明文档及样例配置文件中的注释。
最后,还可以将hostapd设置成系统启启动时自动启动的服务项,这样就不用每次启动系统都要手工加载hostapd了: - [root@alarmpi ~]# systemctl enable hostapd
复制代码弄了接近3天,终于弄好了软ap了。这里提供已经修改好Makefile的8188eu驱动源码、Realtek专用的hostapd源码及软ap模式的相关说明文档的(Realtek 8188eu USB无线网卡驱动(Linux源码版)下载:等待上传),方便有需要的朋友下载使用。 后记:使用内核没有提供驱动的硬件有个不方便的地方——升级内核的时候需要重新编译驱动。而我是把RPi作为无线路由用的,虽说没必要频繁升级内核,但我又不满足于RPi只做无线路由,还打算玩其他东西。最后还是决定更换无线网卡。年后进了一个Tenda W311MI(主控是Ralink RT5370),RPi的固件中直接提供了驱动,省了手工编译安装驱动的麻烦。而且该网卡的驱动是基于mac80211的,可以使用nl80211驱动的hostapd,可以直接使用从更新源直接安装的hostapd。不过还有点不足——无法打开wps,不知道是网卡不支持(网卡的盒子还写着支持的),还是hostapd的问题。算了,又岂能事事尽如人意呢!反正放家里用,又不开802.11n,出到外面连信号都没了,还管他安不安全了。
原文来自:http://gutspot.com/2013/01/30/%E ... %E7%BA%BF%E7%BD%91/ |