techracho のカテゴリわけが android, rails, ios, mac, google となっていて、なんとなく疎外感を感じつつも。
久々に、ネットワークのデバイスドライバがいじりたくなったので、コンパイルしようと思った。本当は FreeBSD でやりたかったけど、デバイスの対応とか、Embedded 環境の整備具合とかの関係で、今回は Linux。社内では Ubuntu が多いので、Ubuntu。LTS ってやつらしいのでなんとなく 12.04 を選択。Kernel Version は 3.5.0。
Ubuntu 12.04 を VM でインストール。Unity とかいう GUI がデフォルトでインストールされて、ちょっとげんなりしつつも、頑張ってネットワークの設定、sshd を立ち上げ、putty 越しに作業開始。
ソースは…ない。kernel もパッケージで管理する Linux のことなので、ソースもパッケージに違いない。探してみたら存在を確認。
% sudo apt-get install linux-source
/usr/src 以下に、
linux-source-3.2.0.tar.bz2 -> linux-source-3.2.0/linux-source-3.2.0.tar.bz2
こんな感じで、bzip で固められたファイルが置かれた。自分で解凍しなければいけない模様。
% sudo tar jxvf linux-source-3.2.0.tar.bz2
Linux の tar コマンドで bzip2 を扱う場合につけるオプションは j。ちなみに FreeBSD の場合は、y。
紛らわしい。BSD tar と GNU tar は違うものですものね。
今回、僕のターゲットは、Ralink 2x00 ドライバ。近年の無線 USB WiFi では、このRalink という会社が結構多いみたい。Buffalo とか IO-DATA とかで購入できる 1000 円くらいの USB Wifi はこのデバイスが多い。ちょっと前だと、Realtek (通称「かに」。ロゴがカニのマークに見えるから。)という会社のチップセットが多かったけど、無線では Ralink の模様。適当に find してみると、ドライバは、以下に存在。
/usr/src/linux-source-3.2.0/drivers/net/wireless/rt2x00
ほほう。
適当にソースを見ながら、今回やりたいことの目星がついてきた。
よし、まずは printk() を挟んでコンパイルっしょ。適当に make すればカーネルモジュールである .ko を吐いてくれるに違いない。
% cd /usr/src/linux-source-3.2.0/drivers/net/wireless/rt2x00 % sudo make make: *** No targets. Stop.
ん?ダメだ。何かオプションが必要に違いない。
適当に上のエラーログでググると、カーネルのソースの場所とかを make コマンドに引数として渡さないといけないらしい。
そうですか。いろんなソースをコンパイルできるようにっていう配慮なんすよね。めんどくさいなあ。
% make -C /usr/src/linux-source-3.2.0 M=`pwd` scripts/genksyms/genksyms: No such file or directory
今度はなんでしょうか??ああ、kernel を一度もコンパイルしないでドライバだけコンパイルしようとしたから、いろいろと auto generate なファイルが足りないのね。
# make oldconfig # make prepare # make scripts
いろいろとファイルを生成してくれました。3つともやらないとダメです。一番最初の oldconfig は、実際に kernel をコンパイルする際に組み込むモジュール群の選択画面です。5分くらいかかりますが、気長に y/n を選択しましょう。 さて、そろそろ Ralink ドライバコンパイルできるんじゃね?
% cd /usr/src/linux-source-3.2.0/drivers/net/wireless/rt2x00 % sudo make -C /usr/src/linux-source-3.2.0 M=`pwd`
成功。たくさんの ko が出来上がりました。
make install と打ってもインストールはしてくれなかったので、手動で ko を対象ディレクトリにコピーします。
% cd /lib/modules/3.5.0-23-generic/kernel/drivers/net/wireless % sudo cp -r rt2x00 rt2x00.ori % cd /usr/src/linux-source-3.2.0/drivers/net/wireless/rt2x00 % sudo cp *.ko /lib/modules/3.5.0-23-generic/kernel/drivers/net/wireless/rt2x00
さて、これで僕の printk() がやっと確認できます。
すでに load されている rt2xxx という名前のついているカーネルモジュールを丁寧に rmmod しまくり、USB wifi をさしなおしました。これで、USB の ID から必要なカーネルモジュールをロードしてくれるはずです。
rt2x00lib: no symbol version for module_layout
ん…?version ???
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
ここまで読んだ方で、正解に気づいた方はさすがです。
Ubuntu 12.04 の kernel version は、3.5.0。apt-get でインストールされた linux-source のバージョンは、3.2.0。Linux の場合、カーネルモジュールのバージョン管理が結構しっかりしているので、動作しないのは当然ですね。
…はー?apt でのソース管理なめてんのー!?
知り合いに聞いたところ、こんなもんとのこと。Ubuntu でカーネル差し替えたかったら、kernel.org から取ってこいとのこと。
ぶへー。めんどくせー。
と、今日はここまで。営業マン(笑)の貴重な2時間が apt のせいで犠牲になりました。。。