無線が最高速でないので、無線のドライバーをソースからビルドしてみようと思いつく。
とはいえ、Rasbery Pi上でコンパイルするのは時間もかかるので、今後を考えてクロスコンパイル環境を作ることにする。
おうちのMac OS Xなら、そのままクロスコンパイルの環境を作ることもできるのだが、色々とめんどくさい。ここは、公式のHPにもあるようにLinuxで環境を作ることにする。ちなみに、Mac OS X上のVirtual Box上でUbuntuを動かし、そこにクロスコンパイル環境を作ることにした。
コンパイル環境は、公式ページに記載されている。Virtual Boxを使ったUbuntu環境の作り方も丁寧に説明されている。
Ubuntuは普段は会社ではServerばかりいじっているのですが、日本語版のデスクトップを落としてきました。Virtual Box用の仮想イメージがあったので、それをそのまま使うことにします。ダウンロードしたzipを解凍して、Virtual Boxでダウンロードしたイメージを指定して起動します。起動後は、普通のUbuntuのセットアップです。インストールした直後に、もろもろアップデートしておきます。Virtual Boxのネットワークの設定をブリッジモードにすればUbuntuからさっくりつながります。
ここからは、ubuntu上の作業。ちなみにUbuntuのバージョンはUbuntu 14.04.1 LTS(64Bit)です。
Webに幾つかUbuntuのクロスコンパイル環境を作る方法があったのですが、Ubuntu 32bit前提のページが混在しており、結局以下の様な方法になりました。
もろもろ必要なパッケージをインストール
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get clean
$ sudo apt-get install build-essential libncurses5-dev
クロスコンパイラーはgitにもあるのですが、Ubuntuの64bitでは動作しないようなので、apt-getでとってきます。
$ sudo apt-get install gcc-arm-linux-gnueabi make ncurses-dev
クロスコンパイラーは、/usr/binに配置されるようです。
$ ls /usr/bin/arm*
/usr/bin/arm-linux-gnueabi-addr2line /usr/bin/arm-linux-gnueabi-gcov-4.7
/usr/bin/arm-linux-gnueabi-ar /usr/bin/arm-linux-gnueabi-gprof
/usr/bin/arm-linux-gnueabi-as /usr/bin/arm-linux-gnueabi-ld
/usr/bin/arm-linux-gnueabi-c++filt /usr/bin/arm-linux-gnueabi-ld.bfd
/usr/bin/arm-linux-gnueabi-cpp /usr/bin/arm-linux-gnueabi-ld.gold
/usr/bin/arm-linux-gnueabi-cpp-4.7 /usr/bin/arm-linux-gnueabi-nm
/usr/bin/arm-linux-gnueabi-dwp /usr/bin/arm-linux-gnueabi-objcopy
/usr/bin/arm-linux-gnueabi-elfedit /usr/bin/arm-linux-gnueabi-objdump
/usr/bin/arm-linux-gnueabi-gcc /usr/bin/arm-linux-gnueabi-ranlib
/usr/bin/arm-linux-gnueabi-gcc-4.7 /usr/bin/arm-linux-gnueabi-readelf
/usr/bin/arm-linux-gnueabi-gcc-ar-4.7 /usr/bin/arm-linux-gnueabi-size
/usr/bin/arm-linux-gnueabi-gcc-nm-4.7 /usr/bin/arm-linux-gnueabi-strings
/usr/bin/arm-linux-gnueabi-gcc-ranlib-4.7 /usr/bin/arm-linux-gnueabi-strip
/usr/bin/arm-linux-gnueabi-gcov /usr/bin/arm2hpdl
作業ディレクトリを作成し、そこにカーネルソースを持ってくる。
$ mkdir raspi
$ cd raspi
$ git clone https://github.com/raspberrypi/linux.git
ここで、カーネルのconfigをするのですが、0からやるのは大変です。いくつかの方法がありますが、一番良いのは、すでに使っているRaspberry Piのconfigファイルを持ってくることです。Raspberry Piをネットワークにつなげ、アクセスできるようにします。先ほどつくったraspiディレクトリにカーネルソースのあるlinuxディレクトリがあるはずなので、そこにRaspberry Piから持ってきたconfigをぶっこみます。
$ cd ./linux
$ scp pi@(Raspberry PiのIPアドレス):/proc/config.gz ./
$ zcat config.gz > .config
クロスコンパイラーを使用するので、CCPREFIXを指定しておきます。
$ export CCPREFIX=/usr/bin/arm-linux-gnueabi-
設定ファイルを読み込んで編集します。色々聞かれるけど、全部デフォになるようReturn。。。と思ったらARM_PATCH_PHYS_VIRTがnになり面倒。。。vi で.configを開いてARM_PATCH_PHYS_VIRT=yにしてから設定ファイルの編集をします。
$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
設定ファイルができたら、makeです。コンパイル速度を上げるためjオプションを付けます。jオプションはコア数×2にすると良いようです。Virtual Boxのコア数が2になってたので、j4を指定します。
$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j4
エラー無しでカーネルできればOK。次はモジュール用のディレクトリを作って、モジュールもコンパイル。
$ mkdir mod
$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules -j4
$ make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=./mod modules_install -j4
余計なファイルは削除
$ sudo rm -rf ./mod/lib/modules/3.18.6+/build
$ sudo rm -rf ./mod/lib/modules/3.18.6+/source
出来上がったモジュールとカーネルをRaspberry Piにぶっこむ。
$ scp -rp ./tmp/lib ./arch/arm/boot/zImage pi@(Raspberry PiのIPアドレス):~/
$ ssh pi@(Raspberry PiのIPアドレス)
Raspberry Piで、以下を実行して、再起動。
pi@xxx $ sudo cp -rp ./lib /
pi@xxx $ sudo chown root:root ./zImage
pi@xxx $ sudo cp -rp ./zImage /boot/kernel.img
pi@xxx $ sudo reboot
これで無事、最新のカーネルになりました。
で、結果として無線は最高速でつながったのか?。。。。ダメでした。。。。
こうなりゃhostapdもコンパイルしてやる。。。あれ、エラーが出てコンパイルできない。
sysinfo.h の頭に以下をつけてコンパイルエラーを回避
#ifndef __kernel_long_t
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
#endif
よし、と思ってhostapdを起動するもエラー。。あ、.configでCONFIG_IEEE80211N=yにしてなかった。。。再コンパイルして無事起動を確認。よし、これで11nでつながる。。。つながらなかった。
どうやら、11nへの壁は厚いようです。
今回参考にさせていただいたHP:
もぐてっく これでダメなら諦めた方が良い程度にRasberry Piのカーネルクロスコンパイル手順をまとめてみた。