Hypriot(Raspberry Pi)でBUFFALO WI-U2-433DM (RealTekチップ) Wifiドングルを動かす方法

BUFFALO WI-U2-433DM は、Realtek8812AUを搭載しており、IEEE802.11ac,a,n,g,b に対応しているという、わりとハイスペックなUSB Wi-Fiドングルなのですが、これをHypriotなRaspberry Pi 2で動かそうとしてちょっと苦労したのでメモ。

ちなみに、 PLANEX GW-USNano2 であればHypriotのデフォルトで入っているので(この記事のような)面倒がないです。

概要

基本の流れはここに書かれています。 Realtek wireless chipset: install the right driver - Easy Linux tips project (Realtek RTL8812AU chipset (0bda:8812)の項)

こちらのリポジトリのドライバをインストールします。 GitHub - abperiasamy/rtl8812AU_8821AU_linux: rtl8812AU_8821AU linux kernel driver for AC1200 (801.11ac) Wireless Dual-Band USB Adapter

準備

$ sudo apt-get update
$ sudo apt-get install -y linux-headers-$(uname -r) build-essential git linux-image-rpi-rpfv linux-headers-rpi-rpfv dkms bc
$ cd
$ git clone https://github.com/abperiasamy/rtl8812AU_8821AU_linux
$ cd rtl8812AU_8821AU_linux/

Makefileの修正

Makefileを編集します。以下のような部分を見つけてください。

CONFIG_PLATFORM_I386_PC = y
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_JB_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
CONFIG_PLATFORM_ARM_PXA2XX = n
CONFIG_PLATFORM_ARM_S3C6K4 = n
CONFIG_PLATFORM_ARM_RPI = n
CONFIG_PLATFORM_MIPS_RMI = n
CONFIG_PLATFORM_RTD2880B = n

これを以下のようにしてください。

CONFIG_PLATFORM_I386_PC = n # y -> n に変更
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_JB_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
CONFIG_PLATFORM_ARM_PXA2XX = n
CONFIG_PLATFORM_ARM_S3C6K4 = n
CONFIG_PLATFORM_ARM_RPI = y # n -> y に変更
CONFIG_PLATFORM_MIPS_RMI = n
CONFIG_PLATFORM_RTD2880B = n

make

$ make
make ARCH=arm CROSS_COMPILE= -C /lib/modules/4.1.12-hypriotos-v7+/build M=/home/pi/rtl8812AU_8821AU_linux  modules
make[1]: Entering directory '/usr/src/linux-headers-4.1.12-hypriotos-v7+'
  CC [M]  /home/pi/rtl8812AU_8821AU_linux/core/rtw_cmd.o
./scripts/recordmcount: 1: ./scripts/recordmcount: Syntax error: end of file unexpected
scripts/Makefile.build:258: recipe for target '/home/pi/rtl8812AU_8821AU_linux/core/rtw_cmd.o' failed
make[2]: *** [/home/pi/rtl8812AU_8821AU_linux/core/rtw_cmd.o] Error 2
Makefile:1384: recipe for target '_module_/home/pi/rtl8812AU_8821AU_linux' failed
make[1]: *** [_module_/home/pi/rtl8812AU_8821AU_linux] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.1.12-hypriotos-v7+'
Makefile:1049: recipe for target 'modules' failed
make: *** [modules] Error 2

あれ?エラーだ。 というわけで、対策します。 ちなみに、ここでエラーがなければ 「では、インストール。」の項目に進んでしまって構いません。

対策 (linux-headers*/scripts再生成)

recordmcountがなんかおかしいようです。 後でわかったことですが、recordmcountというのはカーネルをクロスコンパイル(ラズパイ以外のプラットフォーム上でラズパイのカーネルをビルド)する時に利用するツールの役割を果たすスクリプトで、このためにビルドしたプラットフォームのほうで動作するバイナリになってしまっていることがあるらしいです。

要するに、recordmcountまわり(linux-headersのscripts)をラズパイ内で再コンパイルすればラズパイ上で動くものになります。

$ cd /usr/src/linux-headers-4.1.12-hypriotos-v7+
$ sudo make scripts
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/bin2c
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --silentoldconfig Kconfig
  HOSTCC  scripts/dtc/dtc.o
  HOSTCC  scripts/dtc/flattree.o
  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/data.o
  HOSTCC  scripts/dtc/livetree.o
  HOSTCC  scripts/dtc/treesource.o
  HOSTCC  scripts/dtc/srcpos.o
  HOSTCC  scripts/dtc/checks.o
  HOSTCC  scripts/dtc/util.o
  HOSTCC  scripts/dtc/dtc-lexer.lex.o
  HOSTCC  scripts/dtc/dtc-parser.tab.o
  HOSTLD  scripts/dtc/dtc
  HOSTCC  scripts/genksyms/genksyms.o
  HOSTCC  scripts/genksyms/parse.tab.o
  HOSTCC  scripts/genksyms/lex.lex.o
  HOSTLD  scripts/genksyms/genksyms
  CC      scripts/mod/empty.o
  HOSTCC  scripts/mod/mk_elfconfig
  MKELF   scripts/mod/elfconfig.h
  HOSTCC  scripts/mod/modpost.o
  CC      scripts/mod/devicetable-offsets.s
  GEN     scripts/mod/devicetable-offsets.h
  HOSTCC  scripts/mod/file2alias.o
  HOSTCC  scripts/mod/sumversion.o
  HOSTLD  scripts/mod/modpost
  HOSTCC  scripts/kallsyms
  HOSTCC  scripts/pnmtologo
  HOSTCC  scripts/conmakehash
  HOSTCC  scripts/recordmcount
  HOSTCC  scripts/sortextable
scripts/sortextable.c:31:32: fatal error: tools/be_byteshift.h: No such file or directory
#include <tools/be_byteshift.h>
                                ^
compilation terminated.
scripts/Makefile.host:91: recipe for target 'scripts/sortextable' failed
make[1]: *** [scripts/sortextable] Error 1
Makefile:555: recipe for target 'scripts' failed
make: *** [scripts] Error 2

エラーになりましたが、必要なもの(recordmcount, basic/fixdep, mod/modpost)はできた気がするのでOKとしますw 元のドライバのディレクトリに戻って再度makeします。

$ cd ~/rtl8812AU_8821AU_linux/
$ make
make ARCH=arm CROSS_COMPILE= -C /lib/modules/4.1.12-hypriotos-v7+/build M=/home/pi/rtl8812AU_8821AU_linux  modules
make[1]: Entering directory '/usr/src/linux-headers-4.1.12-hypriotos-v7+'
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/pi/rtl8812AU_8821AU_linux/8812au.mod.o
  LD [M]  /home/pi/rtl8812AU_8821AU_linux/8812au.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.1.12-hypriotos-v7+'

できた!

では、インストール。

$ sudo make install
install -p -m 644 8812au.ko  /lib/modules/4.1.12-hypriotos-v7+/kernel/drivers/net/wireless/
/sbin/depmod -a 4.1.12-hypriotos-v7+

これでリスタートすれば、ドライバ自体は動作します。

sudo reboot

状況確認

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback ....
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether ....
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.28/24 brd 192.168.1.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever
4: wlan1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether ....

wlan(数字)のところでstate UPとなっていれば成功です。

・・・が、上記では2つあるうちの1つがstate DOWNとなっています。 実は、元から動作していたドングルと今回のWI-U2-433DMの2本挿しの状況ですので、新しいほうが動作していないということになります。

というわけで、以下のように /etc/network/interfaces にwlan1に関する設定を追加します。

これはHypriotの例です。素のRaspberry Piではちょっと違うかもしれませんので注意してください。特に(Occidentalis)https://github.com/adafruit/Adafruit-Occidentalisというツールで設定がされています。(/usr/bin/occiというあたり)

sudo vi /etc/network/interfaces
auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
iface eth0 inet6 auto

allow-hotplug wlan0
iface wlan0 inet dhcp
pre-up /usr/bin/occi
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

# 以下の4行を追加
allow-hotplug wlan1
iface wlan1 inet dhcp
pre-up /usr/bin/occi
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

リブートしてみます。

sudo reboot

再度sshして確認。

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 
    link/loopback .....
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether .....
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.28/24 brd 192.168.1.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever
4: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.32/24 brd 192.168.1.255 scope global wlan1
       valid_lft forever preferred_lft forever
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/64 scope link 
       valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether .....

wlan1もstate UPになりました!

これで動作します。

ちなみに、動作すると青いランプが点滅します。ランプが光っていなかったら動作していないと思ったほうが良いと思います。