#はじめに
2015年2月に華々しく爆誕したRaspberry Pi 2(以降RasPi2)。
RasPi2の上でPlanexの802.11ac対応の無線LANドングル「GW-450D」を使うのに、現時点(2015年2月25日現在)ではわりと苦労したので、備忘録として当記事を残します。
作業にあたりましては、みんな大好きEject工作だけではなく最近はRaspberry Pi界隈でも有名なあっきぃ(Twitter:Akkiesoft)さんのはてなブログ(あっきぃ日記)の次の記事を超参考にさせて頂きましたです。この場を借りて感謝致します。ありがてぇ。
- RPi2でドライバーをコンパイルするとExec format errorなモジュールができる | あっきぃ日記
- RPi2でドライバーをコンパイルするとExec format errorなモジュールができるやつのつづき | あっきぃ日記
更に、あっきぃさんの記事内からリンクされた先の一次情報もまとめておきます。ありがてぇありがてぇ。
- Raspberry Piで11ac無線LAN子機『GW-450D』を使うための設定方法 | PLANEX COMM
- GW-450DやWN-AC433UKをRaspberry Piで使う | 簡潔なQ
- Multi-console gamepad driver for GPIO | Raspberry Pi Forum
- Error compiling drivers for Ralink RT2870 | Unix & Linux Stack Exchange
- gcc 4.8 on Raspberry Pi Wheezy | some wide open space
一応、基本的なインストールと初期設定のことは大まかな流れだけ書いておきますが、もう少し詳しく知りたいという方は、あっきぃさんも執筆されているRasPi本(Raspberry Pi〔実用〕入門)やRasPi公式ページのNOOBS Setup Guide(動画)などを参考にすると良いでしょう。おすすめ。
#Raspbianのインストール
まずは普通にRaspbianをNOOBSでインストールしていきます。
2015/2/18にNOOBS 1.4.0(JAISTのミラー)がリリースされていたので、今回はこれをSDフォーマッターでキレイキレイした32GB MicroSDにインストールしました。
ちなみに、インストールといってもダウンロードしてきたNOOBSのZipファイルを展開し、フォルダ内のファイル郡(defaultとosの2フォルダと、bootcode.binやrecovery.cmdlineの10ファイル)をMicroSDカードのルートフォルダに置くだけです。超簡単。
後は、そのMicroSDカードをRasPi2に挿入し、USBキーボード、有線LAN、HDMI経由のディスプレイ、MicroUSB経由の電源(最低でも1A以上のものを使うこと)を接続し起動します。
起動後は、Raspbianを選択(矢印キーで選んでスペースバーで決定)し、キーボードの種類を選び(数字の9がショートカット)、インストールを開始(アルファベットのiがショートカット)します。
インストール完了後は再起動し、いつものraspi-configによる初期設定を行います。とりあえず、最低限の設定はこのあたりでしょうか。
- "Change User Password"からrootパスワードの変更
- "Internationalisation Options"の"Change Locale"から日本語ロケールの追加
- "Internationalisation Options"の"Change Timezone"からタイムゾーン変更
他はお好みで・・・。
ネットワークはDHCPを前提としていますが、必要であれば次のコマンドでIPアドレス設定をします。尚、viが宗教上使えないという方はnanoでも何でもお好きなエディタをお使いください。
$ sudo vi /etc/network/interfaces
■変更例(eth0のところを編集・追記)
auto lo
iface lo inet loopback
iface eth0 inet static
address XXX.XXX.XXX.XXX
netmask XXX.XXX.XXX.XXX
gateway XXX.XXX.XXX.XXX
(以下略)
変更後は、設定を反映させましょう。
$ sudo ifdown eth0;sudo ifup eth0
また、手動設定の場合は参照するDNSサーバも環境に合わせて変更します。
$ sudo vi /etc/resolv.conf
■変更例(nameserver行を編集)
nameserver XXX.XXX.XXX.XXX
ネットワークが使える状態になりましたら、環境を更新します。
$ sudo apt-get update
$ sudo apt-get -y upgrade
$ sudo rpi-update
ここで念の為に再起動します。
$ sudo init 6
#カーネルバージョンの確認
GW-450Dのドライバをコンパイルしていく為に、まずはRaspbianのカーネルバージョンを確認します。私の環境では次の内容が表示されました。
$ cat /proc/version
Linux version 3.18.7-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #758 SMP PREEMPT Mon Feb 23 19:52:56 GMT 2015
この表示の「3.18.7-v7+」がカーネルバージョンです。もしも、このバージョンが当記事と異なる場合は、ドライバのビルド以降の処理が変わってくる可能性がありますので、ご注意ください。
また、このカーネルのビルドに使われたgccのバージョンが「4.8.3」であることも、この結果から確認できました。
#gcc-4.8のインストール
ここで「gcc-4.8」をインストールしたいところなのですが、そのままapt-getなどでインストールすると現時点では「4.8.2」のバージョンがインストールされてしまいます。
$ apt-cache show gcc-4.8
Package: gcc-4.8
Version: 4.8.2-21~rpi3rpi1
(以下略)
4.8系のgccでは、4.8.0 ~ 4.8.2 のバージョンはバグが多いので利用が推奨されません。そこで、今回はJessie(Raspbianの次期メジャーバージョン)のリポジトリを追加します。尚、viが宗教上使えn(以下略)
$ sudo vi /etc/apt/sources.list
■変更例(jessieの行を追加)
deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
(以下略)
設定にWhezzyとJessieの両リポジトリがある状態ので、普段はWhezzyが使われる様に優先順位を付けておきます。
$ sudo vi /etc/apt/preferences
■設定例(ファイルを新規作成し、次の内容で保存)
Package: *
Pin: release n=wheezy
Pin-Priority: 900
Package: *
Pin: release n=jessie
Pin-Priority: 300
Package: *
Pin: release o=Raspbian
Pin-Priority: -10
これで準備が整いましたので、一旦updateして情報を更新してからJessieの方のgcc-4.8をインストールします。途中でサービスの再起動をしても良いか問われますが、「Yes」を選択して構いません。
$ sudo apt-get update
$ sudo apt-get -y install -t jessie gcc-4.8
Raspbianには4.6系のgccもインストールされているので、優先順位を設定して4.8系がデフォルトで使われるようにalternativesを更新します。
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60
gccのバージョンを確認します。
$ gcc -v
(中略)
gcc version 4.8.3 (Raspbian 4.8.3-13)
#Linuxソースの取得とビルド
ドライバをビルドする為に必要なLinuxソースを「rpi-source」コマンドを使用して入手します。
このコマンドではカーネルソースの入手だけではなく、カーネルモジュールのビルドに必要な作業も自動でやってくれます。超便利。
まずは作業に必要な「ncurses-dev」パッケージをインストールします。
$ sudo apt-get -y install ncurses-dev
続いて「rpi-source」を入手し、/usr/bin以下に配置します。
$ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update
完了したら「rpi-source」を実行し、カーネルソースの入手とビルド等を行います。
$ rpi-source
#ドライバソースコードの入手
GW-450Dのドライバをビルドしていく為に、まずはソースコードを準備します。
チップ供給元であるMediaTekのダウンロードサイトからLinux用「MT7610U USB」の最新版ソースコードを入手します。WindowsやMac用のものもあるので間違えないようにしましょう。ペンギンの絵があるやつです。
尚、現時点では、同じ最新バージョン(2013/09/16 ver 3.0.0.2)のものがPlanexのダウンロードサイトからも入手可能です。メールアドレスの入力などが不要なので、こちらのほうがオススメです。MediaTekのページ誤植があるし・・・。
最終的に「mt7610u_wifi_sta_v3002_dpo_20130916.tar.bz2」のファイルが入手できていればOKです。Planexから入手した場合は、Zipファイルを解凍すると入手できます。
より新しいバージョンのソースコードがリリースされた場合はファイル名が異なりますので、適宜読み替えてください。
次に上記のファイルをRasPi上に配置します。慣れている方はscpコマンド等で送れば良いでしょう。
慣れていない方は「startxコマンド」でデスクトップを起動し、更にRasPi上でブラウザを起動させてファイルをダウンロードするか、USBメモリ等でファイルを直接渡してください。
今回はpiユーザのホームディレクトリ(/home/pi)以下にファイルを配置したことを前提に話を進めます。
#ドライバソースコードの修正
入手したドライバソースコードは、そのままでは利用出来ないので修正および設定作業を行います。
まずは展開しましょう。
$ tar xf mt7610u_wifi_sta_v3002_dpo_20130916.tar.bz2
$ cd mt7610u_wifi_sta_v3002_dpo_20130916
続いてファイルを編集します。
まずは「include/os/rt_linux.h」のファイルへカーネルバージョンの差異に対応するための修正を行います。
$ vi include/os/rt_linux.h
■変更例(280~281行目の"int"を"kuid_t"および"kgid_t"に変更)
(略)
typedef struct _OS_FS_INFO_
{
kuid_t fsuid;
kgid_t fsuid;
mm_segment_t fs;
} OS_FS_INFO;
(略)
続いて「common/rtusb_dev_id.c」のファイルにベンダーIDとプロダクトIDを追加します。
$ vi common/rtusb_dev_id.c
■設定例(39行目に"{USB_DEVICE(0x2019,0xAB31)}, /* GW-450D */"を追加)
(略)
USB_DEVICE_ID rtusb_dev_id[] = {
#ifdef MT76x0
{USB_DEVICE(0x2019,0xAB31)}, /* GW-450D */
{USB_DEVICE(0x148F,0x7610)}, /* MT7610U */
{USB_DEVICE(0x0E8D,0x7610)}, /* MT7610U */
(略)
続いて「os/linux/config.mk」のファイルにWPA Supplicantに関する設定を行います。
また、デフォルトではconf/RT2860STA.datがインストールするようになってしまっているのでconf/RT2870STA.datをインストールするように修正します。
$ vi os/linux/config.mk
■変更例1(26行目と31行目の各パラメータを"y"に変更)
(略)
# Support Wpa_Supplicant
# i.e. wpa_supplicant -Dralink
HAS_WPA_SUPPLICANT=y
# Support Native WpaSupplicant for Network Manager
# i.e. wpa_supplicant -Dwext
HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y
(略)
■変更例2(mt7610uの表記を確認し、その後の663行目CHIPSET_DATパラメータを"2870"に変更)
(略)
ifneq ($(or $(findstring mt7650u,$(CHIPSET)),$(findstring mt7630u,$(CHIPSET)),$(findstring mt7610u,$(CHIPSET))),)
WFLAGS += -DMT76x0 -DRT65xx -DRLT_MAC -DRLT_RF -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRTMP_TIMER_TASK_SUPPORT -DA_BAND_SUPPORT -DRTMP_EFUSE_SUPPORT -DNEW_MBSSID_MODE -DCONFIG_ANDES_SUPPORT
#-DRTMP_FREQ_CALIBRATION_SUPPORT
#-DRX_DMA_SCATTER
ifneq ($(findstring mt7650u,$(CHIPSET)),)
WFLAGS += -DMT7650
endif
ifneq ($(findstring mt7630u,$(CHIPSET)),)
WFLAGS += -DMT7630
endif
ifneq ($(findstring mt7610u,$(CHIPSET)),)
WFLAGS += -DMT7610
endif
ifneq ($(findstring $(RT28xx_MODE),AP),)
#WFLAGS += -DSPECIFIC_BCN_BUF_SUPPORT
endif
ifeq ($(HAS_CSO_SUPPORT), y)
WFLAGS += -DCONFIG_CSO_SUPPORT -DCONFIG_TSO_SUPPORT
endif
CHIPSET_DAT = 2870
endif
(略)
続いて「conf/RT2870STA.dat」のファイルに無線LANに関する設定を行います。
$ vi conf/RT2870STA.dat
■設定例(7行目と22~23行目の各パラメータを次の通りに変更)
(略)
SSID=
(略)
AuthMode=WPA2PSK
EncrypType=AES
(略)
ドライバのビルドとインストール
上記の作業が終わりましたら、次はいよいよビルドなのですが、このままmakeを実行しても失敗しています。
原因については前出のあっきぃさんのブログ記事で言及されていますので、そちらをご参照ください。
対処法としては、同じくあっきぃさんの記事内リンクで紹介されているパッケージを導入してLinuxヘッダーを入れ替えるのですが、所謂「野良パッケージ」ですのでこちらは自己責任でお願いします。
$ cd
$ wget http://www.niksula.hut.fi/~mhiienka/Rpi/linux-headers-rpi/linux-headers-3.18.7-v7%2b_3.18.7-v7%2b-2_armhf.deb
このパッケージのインストールには、gcc-4.7等のパッケージが必要ですので追加でインストールします。
$ sudo apt-get -y install -t jessie gcc-4.7
gcc-4.7の準備が整いましたので、先ほどwgetしたパッケージをインストールします。
$ sudo dpkg -i linux-headers-3.18.7-v7+_3.18.7-v7+-2_armhf.deb
このインストールでgccの優先順位が変わってしまいますので、再度設定し直しておきます。
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60
gccのバージョンを確認します。
$ gcc -v
(中略)
gcc version 4.8.3 (Raspbian 4.8.3-13)
いよいよドライバモジュールのビルドを行います。
一部権限のエラーが出るので、makeコマンドにsudoを付けて実行します。
$ cd mt7610u_wifi_sta_v3002_dpo_20130916
$ sudo make
ビルドが完了したらインストールを行います。
$ sudo make install
最後にドライバをインストールしてシャットダウンします。
$ sudo insmod /lib/modules/`uname -r`/kernel/drivers/net/wireless/mt7650u_sta.ko
$ sudo init 0
起動後の確認
再起動が終わりましたら、ifconfigコマンド等で確認をしてra0のインタフェースが存在することを確認します。
$ ifconfig
■表示例
(略)
ra0 Link encap:Ethernet HWaddr XX:XX:XX:XX:XX:XX
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
デフォルトでは、/etc/network/interfacesの無線LANアダプタ名がwlan0となっているので、こちらをra0に編集します。
$ sudo vi /etc/network/interfaces
■設定例(wlan0をra0に置き換える)
(略)
#allow-hotplug wlan0
#iface wlan0 inet manual
allow-hotplug ra0
iface ra0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
あとはwpa_suplicantなり、GUIのWifi Configurationなりを使ってWiFiの設定を行ってください。
私の環境では、次のコマンドでWiFiの設定を/etc/wpa_supplicant/wpa_supplicant.confに登録しました。
$ wpa_passphrase "WiFiのSSID" "WPA2PSKのパスフレーズ" | sudo tee -a /etc/wpa_supplicant/wpa_supplicant.conf
ここまで準備が出来ましたら、ra0のインターフェースをdown/upさせて完了です。
$ sudo ifdown ra0 ; sudo ifup ra0
##おまけ
何故か私の環境では5GHzの802.11nなWiFiに自動接続するのに、起動後に一度ra0をdown/upしてあげなければいけなかったので、/etc/rc.localに次の内容を仕込んでいます。
■設定例
(略)
# By default this script does nothing.
ifdown ra0 ; sleep 1 ; ifup ra0
# Print the IP address
(略)
これで起動後にも5GHzな802.11nのWiFiルータ(私はWiMAX2+のNAD11を利用)に自動接続されるようになりました。
#まとめ
今回はカーネルソース内に罠?があり手順が煩雑でしたが、無事にGW-450DをRasPi2で使える様になりました。5GHz対応なので2.4GHz帯が混み合っている時でも安心ですね。
繰り返しになりますが、あっきぃさん素晴らしい情報ありがとうございました!