Ubuntuでカスタムカーネルをコンパイルしているときに、ファームウェアがどこにあるのかわからないという問題に直面しています。 Ubuntu 8.04では、ファームウェアはドライバーモジュールと同じようにカーネルバージョンに関連付けられています。たとえば、カーネル2.6.24-24-genericは、カーネルモジュールを次の場所に保存します。
_/lib/modules/2.6.24-24-generic
_
およびそのファームウェア:
_/lib/firmware/2.6.24-24-generic
_
2.6.24-24-generic Ubuntuカーネルを「 Alternate Build Method:The Old-Fashioned Debian Way 」に従ってコンパイルすると、適切なモジュールディレクトリが取得され、ファームウェアを必要とするデバイスを除くすべてのデバイスが動作しますIntelワイヤレスカード(ipw2200モジュール)として。
カーネルログは、たとえば、ipw2200がファームウェアをロードしようとすると、ファームウェアのロードを制御するカーネルサブシステムがそれを見つけることができないことを示します。
_ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
_
errno-base.hはこれを次のように定義します。
_#define ENOENT 2 /* No such file or directory */
_
(ENOENTを返す関数は、その前にマイナスを置きます。)
/ lib/firmwareに、カーネルの名前が2.6.24-24-genericディレクトリを指すシンボリックリンクを作成しようとしましたが、同じエラーが発生しました。このファームウェアは、Intelから提供され、Ubuntuでパッケージ化された非GPLです。特定のカーネルバージョンと実際に関係があるとは思わない。 cmp
は、さまざまなディレクトリのバージョンが同一であることを示しています。
それでは、カーネルはファームウェアを探す場所をどのようにして知るのでしょうか?
更新
この解決策 私が抱えている正確な問題を見つけましたが、Ubuntuが_/etc/hotplug.d
_を排除し、ファームウェアを_/usr/lib/hotplug/firmware
_に保存しなくなったため、機能しなくなりました。
Update2
さらなる研究により、さらにいくつかの答えが見つかりました。 udev
のバージョン92までは、プログラム _firmware_helper
_ がファームウェアのロード方法でした。 udev
93以降、このプログラムはfirmware.shという名前のスクリプトに置き換えられ、私が知る限り同一の機能を提供します。これらは両方とも、ファームウェアパスを_/lib/firmware
_にハードコードします。 Ubuntuはまだ_/lib/udev/firmware_helper
_バイナリを使用しているようです。
ファームウェアファイルの名前は、環境変数_firmware_helper
_の_$FIRMWARE
_に渡され、パス_/lib/firmware
_に連結され、ファームウェアのロードに使用されます。
ファームウェアをロードする実際の要求は、システムコールを介してドライバー(私の場合はipw2200)によって行われます。
_request_firmware(..., "ipw2200-bss.fw", ...);
_
これで、ドライバーが_request_firmware
_と_firmware_helper
_を呼び出している間で、_$FIRMWARE
_環境変数を見て、ファームウェア名の前にカーネルパッケージ名が追加されます。
だから誰がそれをやっているの?
カーネルの観点からは、 / usr/src/linux/Documentation/firmware_class/README を参照してください。
kernel(driver):request_firmware(&fw_entry、$ FIRMWARE、device) userspace: -/ sys/class/firmware/xxx/{loading、 -ホットプラグは、$ FIRMWARE のファームウェア識別子と通常のホットプラグ環境で呼び出されます。 -hotplug:echo 1>/sys/class/firmware/xxx /loading kernel:以前の部分ロードを破棄します。 userspace: -hotplug:cat適切な_firmware_image>\ /sys/class/firmware/xxx/data カーネル:PAGE_SIZE単位でバッファーを増やして、イメージを保持するために が入ってくると、 ユーザースペース: -hotplug:echo 0> /sys/class/firmware/xxx/loading kernel:request_firmware()が戻り、ドライバーにファームウェアがあります fw_entry-> {data、size}の画像。何かがうまくいかなかった場合 request_firmware()はゼロ以外を返し、fw_entryは NULLに設定されます。 kernel(driver):ドライバーコードはrelease_firmware(fw_entry)を呼び出しますファームウェアイメージと関連するリソースを解放 します。
カーネルは実際にはファームウェアをまったくロードしません。 「xxxという名前のファームウェアが欲しい」というユーザースペースに通知し、ユーザースペースがファームウェアイメージをカーネルにパイプするのを待ちます。
さて、Ubuntu 8.04では、
$ grep firmware /etc/udev/rules.d/80-program.rules #オンデマンドでファームウェアをロード SUBSYSTEM == "firmware"、ACTION == "add" 、RUN + = "firmware_helper"
あなたが発見したように、udev
はカーネルがファームウェアを要求するときに_firmware_helper
_を実行するように設定されています。
$ apt-get source udev パッケージリストを読み込んでいます...完了 依存関係ツリーを構築しています 状態情報を読み込んでいます...完了 必要312kBのソースアーカイブを取得します。 Get:1 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2(dsc)[716B] Get:2 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2(tar)[245kB] Get:3 http://us.archive.ubuntu.com hardy-security/main udev 117-8ubuntu0.2(diff)[65.7kB] 312kBを1秒でフェッチ(223kB/s) gpg:署名の作成2009年4月14日火曜日05:31:34 PM DSAキーID 17063E6D gpgを使用したEDT:署名を確認できません:公開キーが見つかりません dpkg-source:udev-117 でudevを抽出しています) dpkg-source:udev_117.orig.tar.gz dpkg-source:./udev_117-8ubuntu0.2.diff.gz $ cd udev-117 / $の適用cat debian/patches/80-extras-firmware.patch
ソースを読むと、Ubuntuが最初に/lib/modules/$(uname -r)/$FIRMWARE
を探し、次に_firmware_helper
_を探すようにハードコードされた_/lib/modules/$FIRMWARE
_を書いたことがわかります。他の場所はありません。それをsh
に変換すると、およそ次のようになります。
_echo -n 1 > /sys/$DEVPATH/loading
cat /lib/firmware/$(uname -r)/$FIRMWARE > /sys/$DEVPATH/data \
|| cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data
if [ $? = 0 ]; then
echo -n 1 > /sys/$DEVPATH/loading
echo -n -1 > /sys/$DEVPATH/loading
fi
_
これは、カーネルが予期する形式です。
簡単に言うと、Ubuntuのudev
パッケージには、最初に/lib/firmware/$(uname -r)
で常に見えるカスタマイズがあります。このポリシーはユーザースペースで処理されています。
うわー、これは非常に有用な情報であり、ファームウェアを必要とするデバイス用のカスタムUSBカーネルモジュールを作成する際の問題の解決につながりました。
基本的に、すべてのUbuntuはhal、sysfs、devfs、udevなどの新しいリハッシュをもたらします...そして状況は変わります。実際、私は彼らがhalの使用をやめたと読みました。
それで、これを再びリバースエンジニアリングして、最新の[Ubuntu]システムに関連するようにします。
Ubuntu Lucid(執筆時点で最新のもの)では、/lib/udev/rules.d/50-firmware.rules
使用されている。このファイルは、バイナリ/lib/udev/firmware
、ここで魔法が発生します。
リスト:/lib/udev/rules.d/50-firmware.rules
# firmware-class requests, copies files into the kernel
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware --firmware=$env{FIRMWARE} --devpath=$env{DEVPATH}"
魔法はこれらの線に沿ったものでなければなりません(ソース: Linux Device Drivers、3rd Ed。、Ch。14:The Linux Device Model) ):
loading
data
にコピーloading
にエコーし、ファームウェアのロードプロセスを停止しますloading
(カーネルに信号を送る)udevのLucidのソースページを見ると、udev-151/extras/firmware/firmware.c
、そのファームウェア/ lib/udev/firmwareバイナリのソース、それがまさに続くことです。
抜粋:Lucidソース、udev-151/extras/firmware/firmware.c
util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
err(udev, "error sending firmware '%s' to device\n", firmware);
set_loading(udev, loadpath, "-1");
rc = 4;
goto exit;
};
set_loading(udev, loadpath, "0");
さらに、多くのデバイスはIntel HEX形式(チェックサムやその他のものを含むテキストファイル)を使用しています(wikiには評判もリンクもありません)。カーネルプログラムihex2fw(.HEXファイルのkernel_source/lib/firmwareのMakefileから呼び出されます)は、これらのHEXファイルを任意の設計のバイナリ形式に変換し、Linuxカーネルがrequest_ihex_firmware
、彼らはカーネルでテキストファイルを読むことはばかげていると思ったので(それは物事を遅くするだろう)。
Linux 3.5.7 Gentoo、私は同じ問題を抱えています。解決済み:
emerge ipw2200-firmware
次に/ usr/src/linuxに移動します
make menucofig
デバイスドライバーで、不要なすべてのワイヤレスドライバーを削除し、Intell 2200をモジュールとして設定して再コンパイルします。
make
make modules_install
cp Arch/x86/boot/bzImage /boot/kernel-yourdefault
現在のLinuxシステムでは、これはudev
およびfirmware.agent
。