Raspberry PI 2上的802.11ac网卡驱动编译html
最近在树莓派2上折腾视频,用来作FPV,可是发现2.4G的控会严重干扰2.4G WIFI,在开控的时候个人台式机+外置USB网卡都频频掉线。考虑了一下,5.8G的频段虽然相对2.4G穿透能力更低,可是现阶段5.8G更干净,而且5.8G与2.4G没有倍频关系,不容易互相干扰(1.2G的图传就会干扰2.4G的控)。linux
因而去买了个支持双频11AC的网卡,拿到以后直接插上Pi2,果真——不认,lsusb查了下这个网卡还比较新,用的是RTL8811芯片,官网上提供了Linux下的驱动,和GitHub上的比较了一下还算比较新。仔细看了下驱动包发现里面没有RTL8811的驱动,对比Github上的源码Makefile,认定应该是用RTL8821A的驱动就能够。git
首先在PC上实验一下,解压驱动包,安装脚本加上执行权限chmod +x install.sh,而后./install.sh(须要配好内核代码和编译环境),就能够了,至少这个驱动是能够用的。github
进一步在树莓派上编译内核驱动,首先是要获取树莓派Linux内核源码。树莓派的Linux内核是定制的,源码发布在https://github.com/raspberrypi/linux 。从GitHub上不必定能够找到原装镜像的源码版本,若是源码版本和运行的镜像内核版本不对应,编译出来的内核模块就没法插入。为了减小没必要要的麻烦,最好直接编译一份最新的内核来使用,我是直接在树莓派上作的内核编译,至少须要4个小时。为了节约时间,常常编译的话能够在PC上搭建交叉编译环境,这里就不展开说了。shell
准备内核编译环境和源码,当前的镜像(官方镜像:2015-09-24-raspbian-jessie.zip)中已经包含了大部分编译环境:vim
sudo apt-get bc #内核编译环境需求:高精度计算语言 git clone https://github.com/raspberrypi/linux.git #假设源码在/home/pi/linux cd /lib/modules mkdir 4.1.y #先随便创建一个目录,有可能须要sudo,酌情添加,如下再也不提示
cd 4.1.y
ln -s /home/pi/linux build
ln -s /home/pi/linux source
接下来要获取如今运行内核的内核配置,make的时候就能够根据这个现成配置自动编译(不须要手工去指定各项配置,解除了一件很繁重的工做)。因为最新树莓派内核已经把configs做为一个模块编译,因此须要先加载:网络
sudo modprobe configs
cd /home/pi/linux
zcat /proc/config.gz > .config #获得内核配置文件
make #开始编译内核
执行make以后,须要回答几个问题(由于老版本内核配置没有包含新版本的某些设置),这里我所有按m编译为模块,以便之后须要的时候能够modprobe加载。less
编译开始以后就须要好几个小时等待内核编译完成,若是用SSH等网络方式登录到树莓派上,很容易掉线致使编译中止,最好直接用串口或者screen等方式启动make。函数
在Pi2上若是想快一点能够用make -j4,使用4核编译。测试
内核编译完成后须要继续编译module,这一步比较快:
make modules sudo make modules_install sudo cp arch/arm/boot/Image /boot/kernel-4.1.y.img #将新编译的内核拷贝到/boot
接下来须要配置树莓派使用新内核启动,编辑/boot/config.txt,追加一行:
kernel=/boot/kernel-4.1.y.img
保存退出以后,用sudo reboot重启便可,启动完成以后/lib/modules下面会多一个以当前内核版本命名的目录,这个目录名字和uname -r获取的结果是一致的。cd进去看看,若是没有build和source就像前面同样,把Linux内核源码连接过来。
终于能够开始编译内核驱动了。因为驱动没有提供树莓派的编译选项,须要手工修改Makefile,就再也不执行./install.sh脚本,而是手工调用make:
sudo apt-get install unrar cd /home/pi #假设驱动包在/home/pi
unrar x 8811linux.rar
cd 8811linux/driver/rtl8821AU_linux_v4.3.14_13455.20150212_BTCOEX20150128-51 #具体路径根据版本调整
vim Makefile
在Makefile中确认CONFIG_RTL8821A = y存在,而后搜索CONFIG_PLATFORM_I386_PC将其设为n,并添加一行CONFIG_PLATFORM_ARM_RPI = y。
继续搜索CONFIG_PLATFORM_I386_PC的处理代码块,在其后面添加如下处理脚本:
ifeq ($(CONFIG_PLATFORM_ARM_RPI), 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/ endif
保存退出,到如今准备活动终于完成,能够开始编译驱动:
make sudo make install sudo insmod 8821au.ko
以上是正常编译Linux内核模块的步骤,一样make的时候能够加上-j4参数。
实际上在树莓派上编译的时候有两个坑。首先是编译的时候会报错:
-Werror=date-time/macro “__DATE__” might prevent reproducible builds
解决这个错误只须要在Makefile中查找EXTRA_CFLAGS,并添加一行EXTRA_CFLAGS += -Wno-error=date-time便可。
其次,我这个版本的驱动引用了strnicmp函数,可是目前的树莓派Linux内核源码(4.1.17)并无定义这个函数,不过定义了strncasecmp,功能是相同的。grep驱动代码找到全部的strnicmp替换为strncasecmp便可。
顺利的话insmod以后网卡会亮起来,能够用dmesg和iwconfig进行确认。
最后修改/etc/network/interfaces添加WIFI配置就能够上网了:
allow-hotplug wlan0 iface wlan0 inet dhcp wpa-ssid <YOUR-ACCESS-POINT-SSID> wpa-psk <YOUR-ACCESS-POINT-PASSKEY>
测试了一下5.8G的网络确实干扰少不少,但穿墙效果不行。因为FPV是在空中,较少有阻隔,问题也不大就是了。
另外研究了一下这个网卡是50mW发射功率的,比起正常图传来讲小了不少,用来前期作实验折腾是不错的,后期须要增程的话能够换大功率网卡或者加装双向WIFI功放。