Ubuntu 10.04 – Bluetoothが使えない

WLANが不安定だったのはbackports 3.1のmoduleを入れる事で多分解消出来たっぽいのですが、今度はこの状態だとbluetoothがつかえない事が判明したので、その対応方法についての覚書。

今回試したUSB Dungleはこちら。

[amtap amazon:asin=B006GVCV18]

3.1のbackportsを入れてからBluetoothのUSB Dungleを刺しても以下のメッセージが出てモジュールのロードができなくなってしまいました。

Jan 17 09:06:52 DEMOPC006 kernel: [15048.238246] bluetooth: Unknown symbol security_sk_clone

modinfoでmoduleを調べてみると、backportsのmoduleのようです。

filename: /lib/modules/2.6.32-37-generic/updates/compat-wireless-3.1/bluetooth.ko

alias: net-pf-31

license: GPL

version: 2.16

description: Bluetooth Core ver 2.16

author: Marcel Holtmann marcel@holtmann.org

srcversion: 44F00DEE1CB4AA50846C3B9

depends: compat

vermagic: 2.6.32-37-generic SMP mod_unload modversions 586

parm: disable_esco:Disable eSCO connection creation (bool)

parm: disable_ertm:Disable enhanced retransmission mode (bool)

parm: enable_mgmt:Enable Management interface (bool)

parm: enable_le:Enable LE support (bool)

古いのなら動くかな?と思ったので、とりあえず置き換えてみる。

Linuxのmodule制御用のコマンドはinsmod/rmmod/lsmodがありますが、これはモジュールファイルを直接指定してkernelに組み込んだりはずしたりするためのコマンドで、ドライバの依存関係を解決してくれませんし、大量にあるドライバ類を管理するには少々機能が足りません。

そこで代わりにdepmodとmodprobeというコマンドを使って管理する事が出来ます。depmodはmoduleの依存関係を調べてデータベース化するためのコマンドです。modprobeで依存関係を自動的に解決させるために予め実行しておきます(実行はmoduleファイルの増減があったときだけで良いです。パッケージでmoduleを管理している場合通常意識する必要ありません)。modprobeはmoduleの依存関係を解決しながら組み込んだり外したりできるコマンドです。

今回古いモジュールを新しいモジュールの代わりに使いたいのですが、モジュールのファイルは以下。

/lib/modules/2.6.32-37-generic/updates/compat-wireless-3.1/bluetooth.ko ←新しい

/lib/modules/2.6.32-37-generic/kernel/net/bluetooth/bluetooth.ko ←古い

こんな感じで/lib/modules//kernel以下にKernel Imageに付属するmodule、/lib/modules//updates以下にbackportされたmoduleが格納されています。

depmodがmodules.depを作成するときにモジュールを探しにいっているのですが、/etc/depmod.d/ubuntu.confで指定されているのはupdatesフォルダ、ubuntuフォルダ、標準のフォルダという順番です。

この順番をかえるとまたwlanが使えなくなるので、都合が悪いのでbluetoothだけ古いモジュールを使う様に設定を変更します。

以下のテキストファイルを/etc/depmod.d/bluetooth.confに作成します。

override bluetooth 2.6.32-37-generic kernel/net/bluetooth

override btmrvl 2.6.32-37-generic kernel/drivers/bluetooth

override hci_uart 2.6.32-37-generic kernel/drivers/bluetooth

override bt3c_cs 2.6.32-37-generic kernel/drivers/bluetooth

override dtl1_cs 2.6.32-37-generic kernel/drivers/bluetooth

override bfusb 2.6.32-37-generic kernel/drivers/bluetooth

override cmtp 2.6.32-37-generic kernel/net/bluetooth/cmtp

override bpa10x 2.6.32-37-generic kernel/drivers/bluetooth

override hidp 2.6.32-37-generic kernel/net/bluetooth/hidp

override btmrvl_sdio 2.6.32-37-generic kernel/drivers/bluetooth

override hci_vhci 2.6.32-37-generic kernel/drivers/bluetooth

override rfcomm 2.6.32-37-generic kernel/net/bluetooth/rfcomm

override bluecard_cs 2.6.32-37-generic kernel/drivers/bluetooth

override btusb 2.6.32-37-generic kernel/drivers/bluetooth

override btsdio 2.6.32-37-generic kernel/drivers/bluetooth

override bnep 2.6.32-37-generic kernel/net/bluetooth/bnep

override btuart_cs 2.6.32-37-generic kernel/drivers/bluetooth

ここまで終わったらsudo depmod -aとしてやれば作業完了です。

**2012/1/25追記)2.6.32-38-genericがリリースになっています。KernelをVersion Upした場合2.6.32-38-genericに上記のoverride設定を書き換えてください(backport driver無でiwlagnが安定したかどうか私は現状未確認です)。

**

はまった所: depmod.confのoverrideの書き方。

ソースをてきとうに見るとoverrideルールの所がこうなってた。

格納箇所

nofail_asprintf(&pathname, “%s%s%s/%s/%s.ko”, basedir,

MODULE_DIR, kernelversion, subdir, modname);

比較箇所

for (ovtmp = overrides; ovtmp != NULL; ovtmp = ovtmp->next) {

if (streq(ovtmp->modfile, newpath))

return 1;

if (streq(ovtmp->modfile, oldpath))

return 0;

}

streqはstrcmp呼び出しのマクロなので、exact match。subdirの指定が直接.koが置かれているpathに到達出来るような書き方しないとダメっぽい。・・・あれ?manにはkernel release(uname -r)の部分を*にすればkernel versionによらず置き換えの指定が出来るってあったような気がするけど、これだとwild card展開できない気がする。