Androidを載せたbeagleboard-xmをWiFi APにするまで(其の伍)
今日はzd1211のドライバとwireless-toolsをbeagleboard-xm上のfroyo用にコンパイルしてみる。
wireless-toolsはiwconfigコマンドを使いたいので入れる。
zd1211はドライバなのでいつも通りの方法でクロスコンパイルしてみる。wireless-toolsはユーザランドのプログラムなのでandroidのビルドシステム(Android.mkとmmコマンド)を使ってビルドしてみる。
とりあえずWiFiモジュールがAPモードで動いたらしいところまで。DHCPサーバとDNSリレーサーバのポーティングはまた別の日に。
今回参考にしたページは下記。
http://d.hatena.ne.jp/h_kojima/20110617/1308324429
kernel
WiFiドライバをmakeする前にLinuxカーネルのwireless extensionに関するconfigurationを変更してmakeする。
具体的には、kernelソースの中のnet/wireless/Kconfigを下記のように修正した後で、make menuconfigでwireless extensionに関する設定をONにして、makeする。
$ diff Kconfig Kconfig.org 2c2 < bool "WIRELESS_EXT" --- > bool 17c17 < bool "WIRELESS_PRIV" --- > bool
cd kernel/net/wireless cp Kconfig Kconfig.org(念のためバックアップ) vi Kconfig(上記のdiffのようにKconfigを修正する) make ARCH=arm CROSS_COMPILE=<top-dir>/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- menuconfig make ARCH=arm CROSS_COMPILE=<top-dir>/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- uImage
makeが終わるとuImageが
zd1211
kernelのビルドが終わった後でドライバをビルドする。基本的にはUbuntu上でビルドしたときと同じ手順で、クロスコンパイル用の設定追加を行う。
http://d.hatena.ne.jp/samehada_shiro/20111229/1325149643
つまり、ソースとパッチをダウンロードしてきて、それぞれ展開して、パッチを12番まであてて、makeする。
クロスコンパイル用の設定はar2524drvフォルダのMakefileを下記のように書き換えることで行う。
環境変数ARCHとCROSS_COMPILEを新たに定義して、HOSTとKDIRとKERN_26とKERNEL_SOURCEについては値を書き換える。
で、makeのオプションにARCHとCROSS_COMPILEを足す。
※$(TOPDIR)はandroidソースツリーのトップディレクトリに読み替えてください。
6,7d5 < ARCH=arm < CROSS_COMPILE=$(TOPDIR)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- 9c7 < HOST=$(TOPDIR)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- --- > HOST= 12,14c10,11 < #KERN_VER=$(shell uname -r | cut -b1-3;) < #KDIR := /lib/modules/$(shell uname -r)/build < KDIR := $(TOPDIR)/kernel --- > KERN_VER=$(shell uname -r | cut -b1-3;) > KDIR := /lib/modules/$(shell uname -r)/build 21,27c18,24 < #ifeq ($(KERN_VER), 2.6) < KERN_26=y < KERNEL_SOURCE=$(TOPDIR)/kernel < #else < # KERN_24=y < # KERNEL_SOURCE=/usr/src/linux-2.4 < #endif --- > ifeq ($(KERN_VER), 2.6) > KERN_26=y > KERNEL_SOURCE=/usr/src/linux-2.6.9 > else > KERN_24=y > KERNEL_SOURCE=/usr/src/linux-2.4 > endif 356c353 < $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules --- > $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
ビルドできたらarm用のバイナリができていることを確認する。
$ file zd1211b.ko zd1211b.ko: ELF 32-bit LSB relocatable, ARM, version 1 (SYSV), not stripped
wireless-tools
次はドライバを操作するためのiwconfig等のコマンドを使えるようにするためにwireless-toolsをポーティングする。
最初はwireless-tools本家からソースを持ってきてandroid用にmake環境を作ろうと思っていたがなかなかうまくいかなかったので、いろいろ探していたらテザリングアプリのサイトからandroid用にポーティングされたwireless-toolsを見つけたので、それを使うことにした。
手順は下記のような感じ。svnからソースをcheckoutして、androidのexternalディレクトリにコピーして、mmでmakeする。
1. svnでチェックアウトしてexternelディレクトリにコピー。
svn checkout http://android-wifi-tether.googlecode.com/svn/tools/wireless-tools android-tether-wireless-tools mkdir $(top-dir)/external/wireless-tools cp android-tether-wireless-tools/* $(top-dir)/externel/wireless-tools rm $(top-dir)/external/wireless-tools/.svn (svnフォルダはいらないので削除)
2. androidビルド用の環境設定。envsetup.shをインクルードで実行。TARGET_PRODUCT環境変数の設定。
cd $(top-dir) . build/envsetup.sh export TARGET_PRODUCT=beagleboard
3. mmでビルド。
cd $(top-dir)/external/wireless-tools mm
4. ビルドできたか確認。iwconfigとかが生成されていればOK。
ls ../../out/target/product/beagleboard/system/bin/iw* ../../out/target/product/beagleboard/system/bin/iwconfig ../../out/target/product/beagleboard/system/bin/iwevent ../../out/target/product/beagleboard/system/bin/iwgetid ../../out/target/product/beagleboard/system/bin/iwlist ../../out/target/product/beagleboard/system/bin/iwpriv ../../out/target/product/beagleboard/system/bin/iwspy
動かしてみる
できあがったuImage、zd1211b.ko、iwconfigなどをbeagleboard-xmのSDカードに書き込む。
uImageはbootパーティションに、zd1211bはsystemパーティションの/system/lib/modulesに、iwconfigなどのコマンドは/system/binにコピーする。コピーした後はsyncしてumountを忘れずに。
SDカードにコピーできたらbeagleboard-xmに差し込んで起動。無事起動したら、ドライバをinsmodして、USB無線LANモジュールを差し込んで、iwconfigで設定する。
# insmod /system/lib/modules/zd1211b.ko _____ ____ _ ____ |__ / _| _ \ / \ / ___| / / | | | | | |/ _ \ \___ \ / /| |_| | |_| / ___ \ ___) | /____\__, |____/_/ \_\____/ |___/ ZD1211B - version 3.0.0.56 usbcore: registered new interface driver zd1211b
みなれたロゴがでてきた。insmod成功。モジュール差し込む。
usb 1-2.4: new high speed USB device using ehci-omap and address 6 vendor_id = 2019 product_id = 5303 USB 2.0 Host Release Ver = 4810 EEPORM Ver = 4810 Finsih download Firmware. Ready to reboot PA type: 0 PHYNEWLayout = 1 AiroHa AL2230RF AllowedChannel = 00013fff Region:73
# netcfg lo UP 127.0.0.1 255.0.0.0 0x00000049 usb0 UP 192.168.1.14 255.255.255.0 0x00001043 ath0 DOWN 0.0.0.0 0.0.0.0 0x00001002
うまく認識したっぽい。インタフェースもできてる。Ubuntuのときとちがってこの段階ではまだモジュールのLEDは点灯しない。
この後、iwconfigで設定するがその前にnetcfgでインタフェースをupしておく。するとモジュールのLEDがつく。upするまえにiwconfigを実行しても下記のように失敗する。
# iwconfig ath0 mode "Master" Error for wireless request "Set Mode" (8B06) : SET failed on device ath0 ; Invalid argument.
iwconfigでUbuntのときと同じように設定する。
netcfg ath0 up iwconfig ath0 mode Master iwconfig ath0 essid fragile iwconfig ath0 channel 6 iwconfig ath0 rate 11M iwconfig ath0 key 1111111111
Macbook Airからちゃんとessidがサーチできて、つなぎにいけることを確認した。DHCPサーバ等いれてないのでIPでの通信確認はまだ。(とりえあず静的IPでやってみてもいいかも)
modversoinsについて
ドライバのロード時にmodversionsではまったのでメモ書き。
作ったドライバをinsmodしたときに「disagrees about version of symbol dev_alloc_skb」とかがでてインストールできないことがあった。
原因はカーネルの新しくビルドしたバージョンに入れ替えるのを忘れていたため。
カーネルモジュールはinsmodするときに、カーネルとの互換性チェックのためにmodversionsという仕組みでチェックを行うらしい。
カーネルビルド時にシンボルの一つ一つについてチェックサム的なものが生成され、保存される。それはカーネルのソースディレクトリにあるModule.sysversファイルで確認できる。で、モジュールのビルド時にこの情報が参照されてモジュール側にも記録される。これはmodprobe --dump-modversionsで確認できる。
で、insmodするときにカーネル側とモジュール側のチェックサムの情報がすべて一致するかどうかチェックされるという具合。一致しないものがあると上記の「disagrees about...」というエラーがでてインストールさせてくれない。
詳しくは下記のサイト。
http://d.hatena.ne.jp/enakai00/20110509/1304910773
今回はカーネル側のModule.sysversとモジュール側のmodprobeでの出力結果を比べても同一なのでおかしいなーと思っていたら、そういえばカーネル入れ替えてなかったかもと気づいた。。。。ビルドしてから実際動かしてみるまで結構日にちがたっていたのでカーネルも書き換えていたことを忘れていた。