9
13
2015
21

为树莓派交叉编译 8192eu 网卡驱动

本文来自依云's Blog,转载请注明。

最近打算把闲置了许久的树莓派重新利用起来。交给它的第一个任务是:做路由器。于是去弄了个 USB 无线网卡,型号是 TP-Link WN823N 版本 2.0。买的时候没注意,拿到手才知道这款需要自行安装驱动。还得使用特制版本的 hostapd。

驱动名叫 8192eu,或者 rtl8192eu,随便啦。GitHub 上有多个版本,我使用的是 Mange/rtl8192eu-linux-driver。因为 gcc 及内核更新的原因,需要修改两处:

diff --git a/Makefile b/Makefile
index 0c800f8..85058fa 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,7 @@ EXTRA_CFLAGS += -Wno-unused-label
 EXTRA_CFLAGS += -Wno-unused-parameter
 EXTRA_CFLAGS += -Wno-unused-function
 EXTRA_CFLAGS += -Wno-unused
+EXTRA_CFLAGS += -Wno-date-time

 #EXTRA_CFLAGS += -Wno-uninitialized

diff --git a/os_dep/linux/rtw_android.c b/os_dep/linux/rtw_android.c
index 98f0d31..8a2ee56 100644
--- a/os_dep/linux/rtw_android.c
+++ b/os_dep/linux/rtw_android.c
@@ -337,7 +337,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr)
 {
        int cmd_num;
        for(cmd_num=0 ; cmd_num<ANDROID_WIFI_CMD_MAX; cmd_num++)
-               if(0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num])) )
+               if(0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num])) )
                        break;

        return cmd_num;

然后,本文的主题来了:我需要 ARM 版的驱动!因为我的树莓派没有键盘也没有显示器,也没有网线什么的。除了电源和 SD 卡,它只有一块无线网卡了。所以只能交叉编译了。

本来呢,内核使用的构建系统非常棒,一切都会很顺利的。但是,我不要先交叉编译个 ARM 版内核。于是我遇到了这个问题scripts 目录下的二进制文件是编译模块的时候需要执行的,然而我的机器并不能执行 ARM 版本的二进制。

好吧,不就是一些小程序么。把我本机的复制过去就可以跑了嘛。结果开心地看着各源码文件被编译成目标文件之后,遇到 modpost 报了这么个错误:

FATAL: section header offset=11258999068426292 in file '/ldata/DATA/src/rtl8192eu-linux-driver/8192eu.o' is bigger than filesize=1094666

大概是因为我的系统是 64 位的,然而 ARM 是 32 位的吧。不过我没兴趣去找一个 i686 版本的 modpost 来尝试了。真要在我笔记本上跑 ARM 程序又不是不可以,我们有 qemu 嘛。虽然是模拟器,不过我不觉得它会比在我那树莓派上运行慢 :-)

以下是整个完整的步骤:

首先说明一点,我使用的是 Arch Linux ARM。树莓派官方提供的 Raspberry 镜像里东西太多了,我的 SD 卡放不下我也用不着。而且它是基于 Debian Wheezy 的,没有 systemd 可用。

新建一个目录rpi,开始啦!

因为要运行 ARM 版的 modpost 程序,我们先下载树莓派的 gcc-libs、glibc,并解压出其 /usr/lib 下的文件:

wget https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/gcc-libs-5.2.0-2-armv6h.pkg.tar.xz https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/gcc-libs-5.2.0-2-armv6h.pkg.tar.xz.sig https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/glibc-2.22-1-armv6h.pkg.tar.xz https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/glibc-2.22-1-armv6h.pkg.tar.xz.sig
gpg --verify glibc-2.22-1-armv6h.pkg.tar.xz.sig
tar xf glibc-2.22-1-armv6h.pkg.tar.xz usr/lib || true
gpg --verify gcc-libs-5.2.0-2-armv6h.pkg.tar.xz.sig
tar xf gcc-libs-5.2.0-2-armv6h.pkg.tar.xz usr/lib
[[ ! -f lib ]] && ln -s usr/lib lib

要编译内核模块,当然少不了 linux-*-headers 包了:

wget https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/linux-raspberrypi-headers-4.1.6-3-armv6h.pkg.tar.xz https://mirrors.ustc.edu.cn/archlinuxarm/armv6h/core/linux-raspberrypi-headers-4.1.6-3-armv6h.pkg.tar.xz.sig
gpg --verify linux-raspberrypi-headers-4.1.6-3-armv6h.pkg.tar.xz.sig
tar xf linux-raspberrypi-headers-4.1.6-3-armv6h.pkg.tar.xz usr

不必每次更新 gcc-libs 和 glibc,只要它们能跑 modpost 程序就可以了。但是内核头文件是要和系统上运行的内核匹配的。

我们删掉 ARM 版的 scripts 目录,换上本机的版本。但是 modpost 例外。同时要修改 Makefile.modpost,使之使用 qemu-arm 来运行 modpost 程序:

pushd usr/lib/modules/4.1.6-3-ARCH/build
mv scripts/mod/modpost .
rm -rf scripts
cp -r /usr/lib/modules/$(uname -r)/build/scripts .
sed -i '/^modpost =/s/scripts/qemu-arm scripts/' scripts/Makefile.modpost
mv modpost scripts/mod
popd

最后就可以编译啦。把交叉编译工具链签名)的路径加到 $PATH 里去。还要设置 QEMU_LD_PREFIX 到我们解压出来的那些文件所在的目录好让 qemu-arm 能够找到需要的库文件。然后进入驱动目录,开始编译!

path+=/ldata/DATA/soft/arm-lilydjwg-linux-gnueabi/bin
export QEMU_LD_PREFIX=$PWD
cd ../rtl8192eu-linux-driver
make CROSS_COMPILE=arm-lilydjwg-linux-gnueabi- KSRC=../rpi/usr/lib/modules/4.1.6-3-ARCH/build ARCH=arm
gzip 8192eu.ko

就酱。

试错几次之后,终于把配置写对了,于是我看到树莓派的 Wi-Fi 灯闪动了,随即从系统日志看到 hostapd 和 dnsmasq 都报告它连上网了~然后 ssh 登陆过去:

Last login: Tue Jun 11 22:57:29 2013 from 192.168.2.101

两年零三个月没进去过了呢。然后,我换 USTC 源,执行了pacman -Syu跨越两年零三个月的滚动更新,然而除了很多配置文件有新版本需要手工合并外,并没有发生什么特别的事情,就更没有滚挂了=w=

后来我也尝试在树莓派上直接编译内核模块(因为内核升级了嘛)。结果表明,交叉编译是正确的选择!在树莓派上编译这个模块的时间,我的笔记本估计可以编译出整个内核了……

这是我编译的 8192eu 模块签名文件,对应内核版本 4.1.6。


至于 hostapd,下载这个,把其中的wpa_supplicant_hostapd-0.8_rtw_r7048.20130424.tar.gzhostapd目录下的东西编译了就好。只需要指定CC变量就可以交叉编译成功。

这是我编译的 hostapd签名文件。配置文件中要写driver=rtl871xdrv

Category: Linux | Tags: linux 交叉编译 树莓派 | Read Count: 9291
wicast 说:
Sep 13, 2015 07:30:53 PM

这玩意网口太少当路由器太蛋疼,咱现在是hg255d专门openwrt路由器,开发板当下载鸡以及自建了私有git服务。
还有玩开发板最好是准备一根USB2TTL的线。

Avatar_small
依云 说:
Sep 13, 2015 07:33:33 PM

有线我只需要一个就可以了呀=w=

我可不打算把家里折腾成盘丝洞 :-)

wicast 说:
Sep 13, 2015 07:41:23 PM

802.11n在我这里信道堵塞的爆炸……换ac的成本太高而且衍射能力太差,所以我现在能用网线的都换网线……不然从开发板拖个东西还不如自己下载233333

mugbya 说:
Sep 14, 2015 12:27:22 AM

城会玩系列

jiazhoulvke 说:
Sep 14, 2015 10:16:55 AM

原来依云也有买啊。看你从来没发表过关于树莓派的博文还以为你忍住了呢。哈哈。
我除了刚拿到手的时候研究了一下gpio就没再折腾过了,好多想法都还没实现,一直拿来当下载机用,迅雷那个固件还真是蛮好用的。

猫儿 说:
Sep 14, 2015 02:41:51 PM

真会玩,就是说的我都看不懂- -

reverland 说:
Sep 19, 2015 11:13:03 AM

都是闲置好久的树莓派。。。

mos 说:
Oct 01, 2015 04:28:25 PM

仙子赛高,咱买无线网卡时都是先选Linux支持的,然后raspbian下载安装包就行了。
交叉编译什么的还没玩过。。。

Avatar_small
依云 说:
Oct 01, 2015 05:48:01 PM

选起来太累啦,然后一不小心就选了个支持不好的……

@xuboying 说:
Dec 15, 2015 10:56:56 AM

"如果是用树莓派搭建无线路由器的话,在下载大文件时CPU会被占满,WiFi断掉也是屡试不爽" 会这样么?
http://blog.yuanbin.me/posts/2014/11/arch-wifi.html

Avatar_small
依云 说:
Dec 15, 2015 12:57:41 PM

没关注过 CPU,除了联通 ppp 对端抽风外没出过问题。不管是下大文件,还是开 amule,它都好好的(反而是 amule 经常挂掉)。

@xuboying 说:
Dec 15, 2015 08:30:09 PM

http://item.jd.com/509932.html (http://www.cnblogs.com/wuyinan0126/p/4604109.html)
这个网卡可以用吧?免驱是不是指直接在ifconfig里就能看到接口?

Avatar_small
依云 说:
Dec 15, 2015 08:55:55 PM

你可以参照这个页面 http://elinux.org/RPi_USB_Wi-Fi_Adapters
「免驱」的意思是内核自带了驱动,所以插上就能用。

@xuboying 说:
Dec 15, 2015 09:03:41 PM

所有项的ap mode和ap hoc都是问号 。。。
只能相信原博主了

@xuboying 说:
Dec 19, 2015 03:03:27 PM

装hostapd的时候粗问题了,救命
insserv: warning: script 'privoxy' missing LSB tags and overrides
insserv: There is a loop between service minidlna and privoxy if stopped
insserv: loop involving service privoxy at depth 2
insserv: loop involving service minidlna at depth 1
insserv: Stopping privoxy depends on minidlna and therefore on system facility `$all' which can not be true!
insserv: exiting now without changing boot order!
update-rc.d: error: insserv rejected the script header
dpkg: error processing hostapd (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
hostapd

Avatar_small
依云 说:
Dec 19, 2015 03:15:06 PM

呃,启动依赖循环了……自己改一下相关启动脚本吧,我对 Debian 的服务定制不熟。

@xuboying 说:
Dec 19, 2015 03:25:48 PM

sudo apt-get remove privoxy minidlna hostapd了之后再装还能出现privoxy和minidlna的错误,我也是醉了

@xuboying 说:
Dec 19, 2015 03:32:40 PM

我知道了,要把init.d下的东东也手工删了。。。

请叫我喵 | S-X-ShaX 说:
Feb 06, 2016 11:26:31 AM

话说我最近拿OpenWrt弄了个树莓派路由器,这东西网卡很重要,以前用edup根本不行,后来朋友推荐了一个用着超稳定。

rhett 说:
Jul 05, 2016 11:10:54 PM

我的那台树莓派是第一代,性能(尤其是 IO)有点差,持续下载大文件 CPU 占用率是有点高。无线网卡方面用 ralink 家的稳定很多,印象中在作为 DLNA 媒体服务器时掉过一次线,后面几代的树莓派性能已经好很多了。

Avatar_small
依云 说:
Jul 06, 2016 05:45:49 PM

我的这树莓派应该就是第一代的……I/O 是特别特别差,打开 Vim 都得等好久。不过还好,我只把它当路由器,不用它下东西。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com