================================== これは、 linux-2.6.22-rc4/Documentation/stable_api_nonsense.txt の和訳 です。 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 翻訳日 : 2007/06/11 原著作者: Greg Kroah-Hartman < greg at kroah dot com > 翻訳者 : 池田 宗広 < m-ikeda at ds dot jp dot nec dot com > 校正者 : Masanori Kobayashi さん < zap03216 at nifty dot ne dot jp > Seiji Kaneko さん < skaneko at a2 dot mbn dot or dot jp > ================================== Linux カーネルのドライバインターフェース (あなたの質問すべてに対する回答とその他諸々) Greg Kroah-Hartman この文書は、なぜ Linux ではバイナリカーネルインターフェースが定義 されていないのか、またはなぜ不変のカーネルインターフェースを持たな いのか、ということを説明するために書かれた。ここでの話題は「カーネ ル内部の」インターフェースについてであり、ユーザー空間とのインター フェースではないことを理解してほしい。カーネルとユーザー空間とのイ ンターフェースとはアプリケーションプログラムが使用するものであり、 つまりシステムコールのインターフェースがこれに当たる。これは今まで 長きに渡り、かつ今後も「まさしく」不変である。私は確か 0.9 か何か より前のカーネルを使ってビルドした古いプログラムを持っているが、そ れは最新の 2.6 カーネルでもきちんと動作する。ユーザー空間とのイン ターフェースは、ユーザーとアプリケーションプログラマが不変性を信頼 してよいものの一つである。 要旨 ---- あなたは不変のカーネルインターフェースが必要だと考えているかもしれ ないが、実際のところはそうではない。あなたは必要としているものが分 かっていない。あなたが必要としているものは安定して動作するドライバ であり、それはドライバがメインのカーネルツリーに含まれる場合のみ得 ることができる。ドライバがメインのカーネルツリーに含まれていると、 他にも多くの良いことがある。それは、Linux をより強固で、安定な、成 熟したオペレーティングシステムにすることができるということだ。これ こそ、そもそもあなたが Linux を使う理由のはずだ。 はじめに -------- カーネル内部のインターフェース変更を心配しなければならないドライバ を書きたいなどというのは、変わり者だけだ。この世界のほとんどの人は、 そのようなドライバがどんなインターフェースを使っているかなど知らな いし、そんなドライバのことなど全く気にもかけていない。 まず初めに、クローズソースとか、ソースコードの隠蔽とか、バイナリの みが配布される使い物にならない代物[訳注(1)]とか、実体はバイナリ コードでそれを読み込むためのラッパー部分のみソースコードが公開され ているとか、その他用語は何であれ GPL の下にソースコードがリリース されていないカーネルドライバに関する法的な問題について、私は「いか なる議論も」行うつもりがない。法的な疑問があるのならば、プログラマ である私ではなく、弁護士に相談して欲しい。ここでは単に、技術的な問 題について述べることにする。(法的な問題を軽視しているわけではない。 それらは実際に存在するし、あなたはそれをいつも気にかけておく必要が ある) 訳注(1) 「使い物にならない代物」の原文は "blob" さてここでは、バイナリカーネルインターフェースについてと、ソースレ ベルでのインターフェースの不変性について、という二つの話題を取り上 げる。この二つは互いに依存する関係にあるが、まずはバイナリインター フェースについて議論を行いやっつけてしまおう。 バイナリカーネルインターフェース -------------------------------- もしソースレベルでのインターフェースが不変ならば、バイナリインター フェースも当然のように不変である、というのは正しいだろうか?正しく ない。Linux カーネルに関する以下の事実を考えてみてほしい。 - あなたが使用するCコンパイラのバージョンによって、カーネル内部 の構造体の配置構造は異なったものになる。また、関数は異なった方 法でカーネルに含まれることになるかもしれない(例えばインライン 関数として扱われたり、扱われなかったりする)。個々の関数がどの ようにコンパイルされるかはそれほど重要ではないが、構造体のパデ ィングが異なるというのは非常に重要である。 - あなたがカーネルのビルドオプションをどのように設定するかによっ て、カーネルには広い範囲で異なった事態が起こり得る。 - データ構造は異なるデータフィールドを持つかもしれない - いくつかの関数は全く実装されていない状態になり得る (例:SMP向けではないビルドでは、いくつかのロックは中身が カラにコンパイルされる) - カーネル内のメモリは、異なった方法で配置され得る。これはビ ルドオプションに依存している。 - Linux は様々な異なるプロセッサアーキテクチャ上で動作する。 あるアーキテクチャ用のバイナリドライバを、他のアーキテクチャで 正常に動作させる方法はない。 ある特定のカーネル設定を使用し、カーネルをビルドしたのと正確に同じ Cコンパイラを使用して単にカーネルモジュールをコンパイルするだけで も、あなたはこれらいくつもの問題に直面することになる。ある特定の Linux ディストリビューションの、ある特定のリリースバージョン用にモ ジュールを提供しようと思っただけでも、これらの問題を引き起こすには 十分である。にも関わらず Linux ディストリビューションの数と、サ ポートするディストリビューションのリリース数を掛け算し、それら一つ 一つについてビルドを行ったとしたら、今度はリリースごとのビルドオプ ションの違いという悪夢にすぐさま悩まされることになる。また、ディス トリビューションの各リリースバージョンには、異なるハードウェア(プ ロセッサタイプや種々のオプション)に対応するため、何種類かのカーネ ルが含まれているということも理解して欲しい。従って、ある一つのリ リースバージョンだけのためにモジュールを作成する場合でも、あなたは 何バージョンものモジュールを用意しなければならない。 信じて欲しい。このような方法でサポートを続けようとするなら、あなた はいずれ正気を失うだろう。遠い昔、私はそれがいかに困難なことか、身 をもって学んだのだ・・・ 不変のカーネルソースレベルインターフェース ------------------------------------------ メインカーネルツリーに含まれていない Linux カーネルドライバを継続 してサポートしていこうとしている人たちとの議論においては、これは極 めて「引火性の高い」話題である。[訳注(2)] 訳注(2) 「引火性の高い」の原文は "volatile"。 volatile には「揮発性の」「爆発しやすい」という意味の他、「変わり やすい」「移り気な」という意味がある。 「(この話題は)爆発的に激しい論争を巻き起こしかねない」ということ を、「(カーネルのソースレベルインターフェースは)移ろい行くもので ある」ということを連想させる "volatile" という単語で表現している。 Linux カーネルの開発は継続的に速いペースで行われ、決して歩みを緩め ることがない。その中でカーネル開発者達は、現状のインターフェースに あるバグを見つけ、より良い方法を考え出す。彼らはやがて、現状のイン ターフェースがより正しく動作するように修正を行う。その過程で関数の 名前は変更されるかもしれず、構造体は大きく、または小さくなるかもし れず、関数の引数は検討しなおされるかもしれない。そのような場合、引 き続き全てが正常に動作するよう、カーネル内でこれらのインターフェー スを使用している個所も全て同時に修正される。 具体的な例として、カーネル内の USB インターフェースを挙げる。USB サブシステムはこれまでに少なくとも3回の書き直しが行われ、その結果 インターフェースが変更された。これらの書き直しはいくつかの異なった 問題を修正するために行われた。 - 同期的データストリームが非同期に変更された。これにより多数のド ライバを単純化でき、全てのドライバのスループットが向上した。今 やほとんど全ての USB デバイスは、考えられる最高の速度で動作し ている。 - USB ドライバが USB サブシステムのコアから行う、データパケット 用のメモリ確保方法が変更された。これに伴い、いくつもの文書化さ れたデッドロック条件を回避するため、全ての USB ドライバはより 多くの情報を USB コアに提供しなければならないようになっている。 このできごとは、数多く存在するクローズソースのオペレーティングシス テムとは全く対照的だ。それらは長期に渡り古い USB インターフェース をメンテナンスしなければならない。古いインターフェースが残ることで、 新たな開発者が偶然古いインターフェースを使い、正しくない方法で開発 を行ってしまう可能性が生じる。これによりシステムの安定性は危険にさ らされることになる。 上に挙げたどちらの例においても、開発者達はその変更が重要かつ必要で あることに合意し、比較的楽にそれを実行した。もし Linux がソースレ ベルでインターフェースの不変性を保証しなければならないとしたら、新 しいインターフェースを作ると同時に、古い、問題のある方を今後ともメ ンテナンスするという余計な仕事を USB の開発者にさせなければならな い。Linux の USB 開発者は、自分の時間を使って仕事をしている。よっ て、価値のない余計な仕事を報酬もなしに実行しろと言うことはできない。 セキュリティ問題も、Linux にとっては非常に重要である。ひとたびセキ ュリティに関する問題が発見されれば、それは極めて短期間のうちに修正 される。セキュリティ問題の発生を防ぐための修正は、カーネルの内部イ ンターフェースの変更を何度も引き起こしてきた。その際同時に、変更さ れたインターフェースを使用する全てのドライバもまた変更された。これ により問題が解消し、将来偶然に問題が再発してしまわないことが保証さ れる。もし内部インターフェースの変更が許されないとしたら、このよう にセキュリティ問題を修正し、将来再発しないことを保証することなど不 可能なのだ。 カーネルのインターフェースは時が経つにつれクリーンナップを受ける。 誰も使っていないインターフェースは削除される。これにより、可能な限 りカーネルが小さく保たれ、現役の全てのインターフェースが可能な限り テストされることを保証しているのだ。(使われていないインターフェー スの妥当性をテストすることは不可能と言っていいだろう) これから何をすべきか ----------------------- では、もしメインのカーネルツリーに含まれない Linux カーネルドライ バがあったとして、あなたは、つまり開発者は何をするべきだろうか?全 てのディストリビューションの全てのカーネルバージョン向けにバイナリ のドライバを供給することは悪夢であり、カーネルインターフェースの変 更を追いかけ続けることもまた過酷な仕事だ。 答えは簡単。そのドライバをメインのカーネルツリーに入れてしまえばよ い。(ここで言及しているのは、GPL に従って公開されるドライバのこと だということに注意してほしい。あなたのコードがそれに該当しないなら ば、さよなら。幸運を祈ります。ご自分で何とかしてください。Andrew と Linus からのコメント<Andrew と Linus のコメントへのリンクをこ こに置く>をどうぞ)ドライバがメインツリーに入れば、カーネルのイン ターフェースが変更された場合、変更を行った開発者によってドライバも 修正されることになるだろう。あなたはほとんど労力を払うことなしに、 常にビルド可能できちんと動作するドライバを手に入れることができる。 ドライバをメインのカーネルツリーに入れると、非常に好ましい以下の効 果がある。 - ドライバの品質が向上する一方で、(元の開発者にとっての)メンテ ナンスコストは下がる。 - あなたのドライバに他の開発者が機能を追加してくれる。 - 誰かがあなたのドライバにあるバグを見つけ、修正してくれる。 - 誰かがあなたのドライバにある改善点を見つけてくれる。 - 外部インターフェースが変更されドライバの更新が必要になった場合、 誰かがあなたの代わりに更新してくれる。 - ドライバを入れてくれとディストロに頼まなくても、そのドライバは 全ての Linux ディストリビューションに自動的に含まれてリリース される。 Linux では、他のどのオペレーティングシステムよりも数多くのデバイス が「そのまま」使用できるようになった。また Linux は、どのオペレー ティングシステムよりも数多くのプロセッサアーキテクチャ上でそれらの デバイスを使用することができるようにもなった。このように、Linux の 開発モデルは実証されており、今後も間違いなく正しい方向へと進んでい くだろう。:) ------ この文書の初期の草稿に対し、Randy Dunlap, Andrew Morton, David Brownell, Hanna Linder, Robert Love, Nishanth Aravamudan から査読 と助言を頂きました。感謝申し上げます。