今現在、Linuxには数百万人のユーザがいる。数千人の開発者がいる。市場は拡大しつつある。Linuxは、組み込み用システムでも使われている。ロボット制御システムでも使われている。スペースシャトルに搭載されて宇宙へも行った。私としては、こうなることを十分予見していた、と言いたいし、これはLinuxの世界制覇計画の一環にすぎない、とも言いたいところだが、正直な話、こうなってしまったことに私自身が少々驚いている。私としては、Linuxのユーザが千人から百万人に増えたときのことより、それが一人から百人に増えたときのことをよく覚えている。
Linuxは、移植性と利便性を前提にしたから成功したわけではない。Linuxは、優れた設計理念と開発モデルに基づいて開発されたから成功したのである。Linuxは、このふたつを基盤としたので、移植性に優れ利便性のあるシステムとして構築することも難しくなかった。
JavaやウィンドウズNTは強力な資金力を背景に開発された商用システムである。そういうものと比べた場合、Linuxはどうなのだろうか? 様々な機種のハードウェアが出回っている昨今、移植性を目標にシステムを開発するのは価値あることであり、「Write Once, Run Anywhere(プログラムを一度書けばどんなプラットフォームでも動く)」というJavaの移植性が熱烈な支持を受けているのも事実である。しかし、「Write Once, Run Anywhere」というコンセプトはサン・マイクロシステムズ社が作り上げたわけではない。コンピュータ業界は、ホーリーグレイル(聖杯)を探しもとめるかのように、システムの移植性を長年追い求めてきている。マイクロソフト社も当初は、ウィンドウズNTに移植性を持たせ、インテルチップ上だけでなく、(ワークステーションでよく使われる)RISCチップ上でも動作するシステムにしたいと考えていた。しかし、Linuxにはもとからそうした野心はなかった。そのLinuxが、なんとも皮肉なことに、クロスプラットフォームなシステムとして、このような成功を収めている。
もともとLinuxは、インテルというひとつのCPUアーキテクチャだけを想定して開発された。それが今では、パームパイロットからAlphaワークステーションに至るまで、あらゆるプラットフォーム上で動作するようになっている。PC用オペレーティングシステムとしてはもっとも広範に移植され、Linux上で動作するように書かれたプログラムは様々なプラットフォーム上で「Write Once, Run Anywhere」を実現している。Linuxは、どのようにして当初のもくろみをはるかに超えるものになったのだろうか? その過程を見てみるのは興味深いことである。以下では、Linuxがどのように設計され、どのような努力が開発に注がれた結果、今日あるようなシステムになったのかを考察してみよう。
Amigaコミュニティとモトローラ版の開発
Linuxは、UNIX風のオペレーティングシステムである。しかし、UNIXをベースに開発されたわけではないので、FreeBSDなどと違い、LinuxはUNIXではない。FreeBSDは、そもそも初めからバークレー版UNIX(BSD)をベースに開発され、そのカーネルはBSDのものを直接受け継いでいる。したがってFreeBSDのカーネルは、バークレー版UNIXの直系である。その意味で、FreeBSDは、UNIXファミリーに属するOSであり、UNIXの別バージョンなのである。これに対しLinuxは、UNIX互換なインターフェイスの提供を目標に開発されたものの、カーネル部分は、UNIXのソースコードを参照することなく、まったく独自に書き下ろしたものである。つまり、Linuxは、UNIXの移植版ではなく、まったく別のOSなのである。
実際の話、開発を始めた当初、私の頭にあったのは、自分のCPUベースのPC上で動作するUNIX風のOSを作ることであって、それを他のプラットフォームに移植しようということではなかった。
私が、Linuxのカーネルの移植性を真剣に考えたのは、DEC社の(64ビット RISC CPUの)Alphaへの移植を開始してからである。とはいえ、LinuxがポーティングされたCPUアーキテクチャはAlphaが最初ではない。
Linuxは最初にモトローラ68000系のCPUに移植が試みられた。このCPUは、サン・マイクロシステムズ社、アップルコンピュータ社、そしてAmiga社の初期のコンピュータに搭載されていたCPUである。この作業には、システムプログラミングレベルの開発に関心があったプログラマたちが取り組んでいる。当時のヨーロッパのAmigaコミュニティには、DOSやウィンドウズにいやけがさしていた人たちが実に多かった。
そしてLinuxは、Amiga好きの人たちの努力のおかげで68K(68000系CPUのこと)上で動作するようになった。しかし、私には、彼らがLinuxの移植に成功したとは思えなかった。彼らはLinuxを移植したというより、私がLinuxを書きはじめたときにやったように、68KのCPUアーキテクチャをサポートするためのカーネルモジュールをゼロから開発したからである。つまり、それはLinuxをベースに作成されたLinux風のOSであったが、Linuxシステムそのものではなかった。
ある意味で、この最初のポーティングは移植性のあるLinuxの枠組みを作る役には立たなかった。しかし、それとは別の意味で、その目的に大いに貢献したとも言える。私は、Alphaアーキテクチャへの移植を検討しはじめたとき、68Kでの経験を思いだし、あのときと同じやり方で取り組むのは良くない、と思ったからである。前と同じ方法を採用したら、三つの異なるソースコードをサポートしなければならなくなってしまう。そうすることは、プログラミング的には可能であっても、メンテナンスは不可能に近い。この最初のときと同じ方法を採用したら、Linuxが移植されるたびに、別バージョンのソースコードが誕生する。そのようなLinuxのカーネルをサポートするためには、それらすべてのバージョンのソースコードを逐一把握していなければならない。それは私が求めていたLinuxの姿ではなかった。私が求めていたのは、単一のソースコードツリーの中に、Alphaアーキテクチャ用のディレクトリ、68K用のディレクトリ、そしてx86用のディレクトリというように、各アーキテクチャに依存するディレクトリツリーを整理して持つようなシステムであった。
そのため、Alphaへの移植に際して、私はLinuxのカーネル部分を大幅に書き換えなければならなかった。それでも、私が頑張れたのは、当時広がりつつあった開発者コミュニティといかに協力して、Linuxを改良していくかを目標にしたからである。
マイクロカーネル
私がLinuxのカーネルを書きはじめたころ、当時の定説のひとつに、システムの移植性を高めるにはマイクロカーネルのアーキテクチャを使わなければならないという考え方があった。
Linuxのような単体の(モノリシックな)システムでは、メモリ空間がカーネル空間とユーザ空間とに分割される。OSのカーネル部分はカーネル空間にロードされ、その部分のメモリ領域を使って、カーネルレベルのオペレーションを実行する。これらのオペレーションとは、システムレベルでのスケジューリング、プロセス管理、シグナル、デバイス入出力、ページング、そしてスワッピングなどである。これらは、OS上で動作するアプリケーションプログラムが必要とする基本機能である。カーネルは、CPUとのやりとりに使用されるドライバなどを含むので、単体のカーネルはCPUのアーキテクチャに依存するとされている。
マイクロカーネルも、プロセス間通信やプロセス管理、スケジューリング、下位レベル入出力といった処理を実行するが、通常のカーネルに比べると、最小限の基本的な機能だけを提供する。マイクロカーネルでは、アーキテクチャに依存する多くの機能がユーザ空間で動作するサーバプロセスとして実現されるので、ハードウェアに対する依存性を減少させることができる。マイクロカーネル方式では、プロセス管理機能やメモリアロケーション機能、そしてリソースアロケーション機能とハードウェア間のやりとりを抽象化するので、異なるアーキテクチャのCPUへの移植作業を最小限に抑えることができる。
と、いうことで、私がLinuxの開発に取り組みはじめた一九九一年頃、移植性のあるシステムを作るなら、当然マイクロカーネルにすべきである、と考えられていた。しかも、マイクロカーネルは、当時のコンピュータサイエンティストたちの研究意欲をかきたててやまないテーマだった。しかし、私は現実主義者なので、マイクロカーネルを実験的な性格のものと考えていた。単体のカーネルよりも明らかに構造が複雑なものと考えていた。そして、単体のカーネルより処理速度が著しく遅いと考えていた。とりわけ、現実にOSを使用する場合は、その処理速度が問題になる。だからこそ当時、マイクロカーネルを最適化し、通常のカーネル同様の速度で動作ようにするために巨額の研究費が投入されていた。そして、当時の研究論文は、マイクロカーネルを最適化するための様々な方法を紹介していたが、皮肉なことに、それらはほぼそっくりそのまま従来のカーネルにも適用でき、しかもそれらの実行速度を速くできる方法だった。
実際、これを知って私は、マイクロカーネルを中心に据えたアプローチに不信感を抱くようになった。マイクロカーネルのアプローチは、より多くの研究費を引っぱりだすための大義名分のように思われたからである。とはいっても、当時の研究者たちは、それを承知のうえで意図的にマイクロカーネルのアプローチを研究対象にしていたわけではない。彼らは、マイクロカーネルを研究するか、そうでなければカーネルの研究に一切タッチしないという雰囲気の中にいた。つまり、彼らは、マイクロカーネルを研究テーマに選ばざるをえない仲間内のプレッシャーの中で研究活動に従事していた。それに気づかなかった彼らは、愚かだったのかもしれない。周囲の状況や雰囲気に惑わされていたのかもしれない。この点については、ウィンドウズNTの設計者たちも例外ではなかった。彼らは、自分たちの最終成果物がマイクロカーネルにならないことを重々承知のうえで、さも自分たちがマイクロカーネルを開発目標としているかのごとく振る舞っていた。
幸いなことに、私は、マイクロカーネルを研究しなければならないというプレッシャーを身近に感じたことはなかった。当時私が在籍していたヘルシンキ大学では、一九六〇年代後半からOS研究がなされていたこともあって、今さらカーネルを研究テーマに選ぼうと考える人たちはいなかったからである。OSの基本部分は、七○年代の初めにすでに十分研究しつくされた分野であることを考慮すれば、ある意味で、ヘルシンキ大学の研究者たちの見方は正しかった(Linuxのカーネルも、OSの基本部分であることに変わりはない)。一般的なカーネルについては、七○年代初頭以降にも研究されているが、それらは自己満足のためのおさらいといった程度のものである。
移植性の高いソースコードは、ハードウェアの仕様を抽象化するレイヤ(モジュール群)を作成しなくても、巧みにコーディングすれば書けるものである。マイクロカーネルに移植性を持たせようとするのは、四角いタイヤを使って並外れてスピードの速い車を作ろうとするようなもので、単に時間の無駄である。カーネルのように処理速度が目もくらむように速いものを抽象化しようとする試み自体が、非生産的である。
もちろん、マイクロカーネルを研究する目的は処理速度以外にもある。しかし、目標の違いについて我われは考えなければならない。マイクロカーネルの研究は、考えうるあらゆる機種との間で広範な移植性を持つカーネルの設計を理論的に追及することを目標としている。しかし、私がLinuxで目指していたのは、理論的に考えられるマシン相手の移植性ではなく、現実に使われているマシン相手の移植性であった。
Alphaおよび他のアーキテクチャへの移植
私は、Alphaへの移植作業を一九九三年に開始し、ほぼ一年がかりで、基本部分のほとんどを移植するのに成功した。これは、私が最初に取り組んだ、Linuxカーネルのインテル以外のアーキテクチャへの移植作業であり、技術的には難しかったが、この作業を経験したことによって設計の基本方針がある程度できあがった。そのおかげで、他のアーキテクチャへの移植がだいぶ楽になった。
私は、特定のアーキテクチャへの移植性を念頭において、Linuxカーネルを書いたわけではない。Linuxカーネルは、ターゲットとなるアーキテクチャが動作するうえで必要となる機能を前提に書かれている。たとえば、私は、68K、SPARC、Alpha、PowerPCといったCPUがメモリ管理をどう行なっているかを徹底的に調べてみた。すると、細かいところは機種に依存するが、ページングやキャッシなどは基本的に最小限の機種依存性しかないことがわかった。そこで、Linuxカーネルのメモリ管理は、機種に依存している部分をできるだけ最小限に抑え隠蔽できるようにしたうえで、依存部分と非依存部分のインターフェイスを一様な形で持てるように設計すれば、移植性を高めることもそれほど難しくはないだろうという結論に達した。
移植にかかわる問題も、こちらの考え方ひとつで単純化される。たとえば、CPUにページング機能があるとしてみよう。とすると、このCPUには、仮想記憶メカニズムにメモリのどの部分を使用すべきかを知らせる(メモリ管理機構の)アドレス変換バッファ(TLB)がなければならない。もちろん、TLBがどのように実装されているかはわからないが、移植に際して必要なのは、このバッファがメモリアドレスをどうマップしているかということだけである。つまり、カーネルの移植に際して、機種依存の部分がいくつかあったとしても、たいては、このTLBの場合のように、背景となるメカニズムがどう動作するかがわかっていれば知識としては十分なのである。
もうひとつ、私が守っている経験則は、コンパイラから見てコンパイル時にすでに定数とみなせるような変数は、最初から定数となるようにコーディングすることである。このように書かれているソースコードからは、コンパイラがより最適化されたコードを生成できる。また、定数の定義もしやすくなるので、これは明らかに賢明な方法である。
各アーキテクチャに共通する部分を明らかにしながらクロスプラットフォームなOSを設計すると、おもしろいことに、よりハードウェアの仕様に適したOSを設計できる。ちょっと信じられない、と思われるかもしれないが、各種アーキテクチャに共通な一般則は、カーネルを最適化し性能を向上させるために必要な情報と結果的に同じであることが多い。これは重要なことである。
たとえば、様々なアーキテクチャでページング機能がどのように実装されているかを調べ、その結果に基づき、ページング機能のデータ構造を三段階のツリー構造のリストで管理することにしたとしよう。そして、この想定のもとに設計作業を進めていくと、性能を向上させることにだけを念頭において作業した場合同様、三段階のツリー構造に行き着くのである。言い換えれば、移植性を目標にせず、特定のアーキテクチャ上でカーネルをどれだけ最適化できるかだけを念頭において作業を進めていたとしても、ページング機能は三段階のツリーで管理するのがいちばんいい、という結論に達することが多い。
単なる偶然でそうなるわけではない。アーキテクチャがその細部で一般的な設計から逸脱するのは、往々にして設計自体に欠陥があるからである。移植性を念頭において、機種依存な実装をできるだけ回避しようとする努力は、欠陥のある設計を回避する努力につながり、より適正な設計をもたらすことになる。基本的に私は、現に使われているアーキテクチャの仕様に対して、理論的に優れているとされている手法を適用することにした。理論的アプローチと現実的アプローチの中間をいくことで目標に達成しようとしたのである。
カーネル空間とユーザ空間
Linuxのような単体のカーネルでは、その部分の変更がシステムの他の部分に影響を及ぼすことが考えられる。したがって、カーネルのコードや機能の変更には細心の注意を払わなければならない。
カーネルに新しいシステムコール(アプリケーションプログラムから見えるOSのカーネル部分とのインターフェイス)を組み込むことは、基本的に避けなければならない。新たなシステムコールを追加したいと誰かが言いだしたときには、とりわけ慎重に対処しなければならない。その種のインターフェイスは、いったんユーザに提供されてしまうと、誰もが変更できるようになってしまう。そして誰かがシステムコールを変更すれば、その変更が反映されたシステムを誰も使用せざるをえない。システムが存続する限り、そのインターフェイスをサポートし続けるはめにはなりたくない。
システムコール以外であれば、追加してもさほど問題にならない。たとえばディスクドラバがなければ、追加する以外の選択肢はない。そして、ディスクドライバは、他の部分に悪さをすることをさほど心配せずに追加できる。Linuxに新しいディスクドライバを実装すれば、既存ユーザに迷惑をかけることなしに、Linuxのユーザ層をさらに拡大できる。
カーネルの変更に際しては、本当に適切な機能なのだろうか、適切な実装方法なのだろうかといった点を考慮して、バランスのとれた決定をしなければならない。ときには、機能自体は適切でも、実装方法が悪く、特定のこと以外何もできないことがある。
これはどちらかと言えば仕様の問題なのだが、誰かがファイル名に十四文字以上は使えないようなばかげたファイルシステムを実装したとしよう。こういう制限があると、ファイルシステムを拡張しようと思ったとき、四苦八苦しなければならない。したがって基本的な部分にこうした制限を設けるのは、是が非でも避けなければならない。ファイル名に十四文字以上は使えないファイルシステムが実装されたりすると、プログラム間のファイル名の受け渡しも同様な制限の対象となりうる。そのような場合、制限以上の長さのファイル名をやりとりしようとすれば、システムがクラッシュしてしまう。
今現在、こんなばかげたことをやっているベンダーはマイクロソフト社だけである。DOSやウィンウズでファイルを読もうとすれば、八文字プラス三文字の合計十一文字以下というファイル名の長さの制限に従わなければならない。ウィンドウズNTではDOSやウィンドウズより長いファイルネームを使えるようになった。しかし、マイクロソフト社はそれを可能にするために、ファイル名の取り扱い以外はすべて従来のものと同じ処理を実行するルーチンを、まったく別に作成しなければならなかった。これは、昔の不備な仕様がその後の作業に悪影響を及ぼした典型的な見本である。
同じような例が、プロセスの生成を向上させるために(ベル研究所の実験的な次世代OSである)Plan9オペレーティングシステムで開発されたシステムコールである。プロセスの生成とは、プログラムの実行を二分割し、それぞれの処理を平行して実行させる方法である。Plan9にはR−Forkと呼ばれる機能があった(SGIではS−Procと呼ばれるようになっている)。R−Forkは、同じアドレス空間を共有するふたつのプロセスを生成する機能を提供するシステムコールで、スレッド(並列処理における実行単位のひとつ)処理の際に使用するにはとくに便利なものだった。
SGIやPlan9のプロセス生成のインターフェイスは、同じアドレス空間を共有するふたつのプロセスが別々のスタックを使うように実装されていた。ひとつのスタックしか使わない通常実装では、ふたつのスレッドで同じアドレスを使えば、そのアドレスはメモリ上の同じ位置を指すことになる。ところが、別々のスタックを使うように実装されていれば、スタックポインタを共有しながら、ふたつの異なるメモリ上のアドレスを利用することができる。
これは実に優れたアイデアなのだが、スタックにかかるオーバーヘッドを考えると、実際には使いものにならない。しかし、開発者たちがその事実に気づいたときは、すでにいくつものプログラムでそのシステムコールが使用されてしまっていて、システムコール自体を別の形で実装するには手遅れだった。そのため、彼らは、スタックにオーバーヘッドがかからないシステムコールを別途書き加えなければならなかった。なお、Linuxにも同様の処理を行なうシステムコールがあるが、こちらは最初から適切に実装されている。
知的所有権の行使を前提に商用ソフトウェアの開発を行なっている企業の中には、設計上欠陥のあるアーキテクチャをそのままエンドユーザに押しつけるところもあるが、Linuxでは勝手にそのようなことはしない。
結局のところ、Linuxの開発管理と設計方針は同じゴールを目指している。実践的な見地から見て、私は、Linuxカーネルのシステムコールを開発・設計している数多くの開発者をとうてい管理できない。管理できたとしても、カーネル自体をコントロールできない。これができないことで、Linuxのカーネルが小さくなっている。しかし、設計的見地から見て、Linuxのカーネルが小さくなっていることが妥当なのである。カーネルを小さくしておくことで、システムコールの数を最小限に抑えることができる。将来の開発に課せられる制限を最小にしておくことができる。
もちろん、Linuxも無傷なわけではない。Linuxは、UNIXから様々なインターフェイスを継承しているからである。ときには私も、それらを保守する必要がなければどんなによかったかと思うことがある。しかし、それでもLinuxはゼロからスタートしたのではないオペレーティングシステムとしてはよくできている。また、UNIXのアプリケーションが使えるという利点がほしいのなら、そのお荷物をいくらか引き受けるのはしかたのないことかもしれない。UNIXのアプリケーションが使えることは、Linuxの人気にまぎれもなく貢献している。そこを考えると、UNIXの遺産を継承したことは差引オッケーのトレードオフである。
GCC
UNIXも、移植性という点ではサクセスストーリーを地で行っている。UNIXのカーネルの移植性が高いのは、他の多くのカーネル同様、C言語のおかげである。Cコンパイラが多くのアーキテクチャで幅広く使えるおかげで、UNIXをそれらのアーキテクチャに移植することが可能になった。C言語あっての移植性の高さは、Linuxも同じである。もともとコンパイラというのは、OS上でプログラムを開発するために、基本的に必要とされるものである。
UNIXの事例を見れば、Cコンパイラが重要なのは明らかである。私は、このコンパイラの重要性を考えて、GNU一般公有使用許諾(GNU General Public License又はGNU GPL)の下にLinuxをライセンスしている。GPLは、GCC(GNUプロジェクトがフリーソフトウェアとして提供しているCコンパイラ)を使用するためのライセンス形態である。GNUプロジェクトはGCC以外にも様々なフリーソフトウェアを提供しているが、ことLinuxに限って言えば、どれもGCCほど重要とは思えない。私は個人的にも、GCCにしか関心がない。だから、Emacsエディタがそれほどよいとは思わない。もちろんLinuxのほうがEmacsより大きいが、Linuxにはそうなるだけの理由が少なくともある。
Linuxのカーネルは、通常のアーキテクチャを対象とした場合、コンパイラがよっぽどひどくない限り、移植性は問題にならない。将来開発されるCPUについても、カーネル部分の移植であれば、そのCPUアーキテクチャがどうなっているかを心配する必要はあまりない。私が心配しているのはコンパイラと新しいCPUの相性である。たとえば、コンパイラから見ると、インテル社のビットチップのMercedのアーキテクチャは、いままでのチップとはまったく違っている。
したがって、(基本的にC言語で書かれている)Linuxの今後の移植性がどうなるかは、GCCが主要なチップのアーキテクチャに今後どれくらい移植されるかにかかっている。
カーネルモジュール
Linuxのカーネルについては、できるだけモジュール化されたシステムにしなければならないということが、開発のかなり早い段階で明らかになった。オープンソース方式で開発されるシステムは、絶対にモジュール化されなければならない。そうでなければ、同時並行的にいくつもの作業を推進するのが非常に難しくなる。複数の人間がカーネルの同じ部分に取り組んで、意見を異にする状況を見るのは、私にとって苦痛でしかなかった。
システムがモジュール化されていないと、変更が施されたファイルを一つひとつ点検し、他の部分に悪い副作用がないことをいちいち確かめなければならない。Linuxのような規模のシステムでこれをするとなれば、膨大な数のファイルをチェックするはめになる。モジュール化されていれば、ファイルシステムの改良版(修正されたソースコードの差分ファイル)が送られてきて、たとえそれが信用できないとしても、他の誰もがこのファイルシステムを使っていないことは確かなので、その改良版がLinuxのその他の部分に悪影響を与えることを心配しないですむ。
たとえば、ハンス・ライザーが新しいファイルシステムに取り組んでいて、それがようやく完成しているが、この時点では、まだLinuxのカーネル2.2に組み込めるようにはなっていない。しかし、Linuxカーネルはモジュール化されているので、私がそれを試してみたいと思えば、実際に試すこともできる。そして、それはさほど大変な作業でもない。大切なのは、システムをモジュール化して、開発者の一人ひとりが他の人の邪魔にならないようにすることである。
Linuxは2.0カーネルによって、実に大きく成長した。この時点で、我われは動的にロード可能なカーネルモジュールの枠組みを追加した。これによって、モジュールを書くためのはっきりとした構造が作られ、Linuxはさらにモジュール化されたシステムになった。プログラマたちは、互いに邪魔する危険を冒すことなく、各人が担当モジュールの開発に取り組むことができるようになった。私も、カーネル本体の変更点をちゃんと管理できるようになった。そういうわけで、ここでも開発者の管理を考慮して下した決定と、コード管理をどうするかを考えて下した決定とが、奇しくも一致している。Linuxの開発に携わる多くの人たちの作業の整合性をとるには、このカーネルモジュールのようなソフトウェア的メカニズムが必要とされた。そして、設計上の観点から見て、その決定は妥当だったのである。
ランタイムローディング(動的なモジュールのメモリへのロードメカニズム)との関連で、Linuxカーネルのモジュール化をどう評価するかについては、まだはっきりした結論が出ていない。ランタイムローディング自体に対しては、誰もが優れた評価を与えているが、新たにふたつの問題が発生している。一つは、技術的問題である。しかし、技術上の問題は(たいてい)もっとも容易に解決がつくのが常である。もうひとつは、非技術的な問題ではあるが、これは技術的な問題以上に重要である。つまり、どの時点でモジュールをLinuxからの派生物とみなし、GPLの管理下に置くかという問題である。
たとえば、最初のモジュールインターフェイスを書いた開発者たちの中に、SCO(サンタ・クルーズ・オペレーションズ)社のためにドライバを書いた人たちがいた。そして彼らは、ソースコードを公開しようとしなかったが、Linuxにバイナリを供給するための再コンパイルには喜んで応じてくれた。そのとき私は、このような状況に対して(ソースコードの公開を義務づけている)GPLを厳格に適用することは道義上できないと判断した。
GPLは、GPLでライセンスされているソフトウェアを「派生させる形で作成されたもの」はGPLでライセンスされなければならない、と定めている。ところが、派生物とは何かを明確に定義することは難しい。これより先を派生物とする、というような方法で明確化しようとすればすぐに、その線をどこで引くかという問題に直面してしまう。
Linuxの場合、システムコールのインターフェイスは、カーネルそのものには含まれない部分とみなしている(というか、私がそう宣言したということになる)。これにより、Linux上で動作するプログラムにはGPLが適用されない。私は、かなり早い段階でこの決定を下し、その事実を周知させるために特別なREADMEファイルを追加している(付録B参照)。そのため、商用ベンダーもGPLへの抵触を心配をすることなしに、Linux向けプログラムを開発できる。
この結果、モジュールメーカーは、通常のインターフェイスを使ってロードするように実装する限り、モジュールをLinux向けに書き、それに対して著作権を持つことができるようになった。とはいえ、Linuxカーネルとモジュールの関係には白黒がついていない部分がまだあるので、それを悪用することはできる。GPLは、モジュールインターフェイスのようなものの取り扱いをはっきり規定していないが、単にGPLの裏をかく目的だけのために、私の設定したガイドラインを濫用するような人が出てくれば、その人物を告訴することも考えなければならない。しかし、Linuxカーネルを悪用しようと考える人はいないだろうと、私は思っている。これまでのところ、企業がLinuxカーネルに関心を示したのも、その開発モデルに魅力を感じてのことである。
Linuxが多くの人たちに支持されているのは、ソースコードそれ自体に魅力があることにもよるが、大勢の人びとが協力し合っていることも大きい。誰かがLinuxを乗っ取り、商用バージョンを作って売ろうとしたら、それは、オープンソース開発モデルというLinuxの魅力に欠けるものになってしまう。
移植性の現状
現在までに、Linuxは、マイクロカーネルのアーキテクチャでのみ可能だと当初考えられていたOSの移植性に関する設計上の目標をかなり達成している。
Linuxは、ハードウェアの仕様を抽象化するレイヤ(モジュール群)を持っていないが、様々なアーキテクチャに共通して見られる要素を引き出し、汎用性のあるカーネルモデルを構築することで移植性の高いものとなっている。しかも、マイクロカーネルを採用することで移植性を高めようとしなかったので、処理速度も犠牲になっていない。
Linuxでは、カーネルをモジュール化したことにより、ハードウェアに特有のコードをモジュールに閉じ込めることができる。これによってLinuxのコアカーネルは、きわめて移植性の高いものとなっている。カーネルモジュールを効果的に使っているよい例のひとつがデバイスドライバである。ハードウェア特有の処理をすべてコアカーネルに含めてしまえば、カーネルを速くすることはできるが移植性はなくなる。ハードウェア特有の処理をすべてユーザ空間に閉じ込めてしまえば、システムは遅くなるか、不安定になるか、あるいは遅くて不安定なものになってしまう。しかし、ハードウェアに特有のコードをモジュールに閉じ込めるアプローチは、コアカーネルに閉じ込めるアプローチとユーザ空間に閉じ込めるアプローチの中間で、ちょうど具合がいいのである。
Linuxの移植性へのアプローチは、開発者コミュニティにとってもよいものであった。移植性を高めるために決定したことが、私の管理すべき範囲をせばめるとともに、多数の人びとが同時にLinuxの様々な部分に取り組むことを可能にしたからである。また、基本的なアーキテクチャをはっきりさせたうえでLinuxの開発に取り組んだことで、私はどのようなカーネルの変更が問題になるかがわかった。個々のCPUアーキテクチャ用に別々のソースコードを維持する必要もなくなった。したがって、大勢の人がLinuxの開発に取り組んでいても、コアカーネルがどうなっているかを私は常に掌握していられる。しかも、カーネルがモジュール化されていることによって、プログラマたちは、本来独立したものであるべき各モジュールの開発に別個に取り組むことができる。
Linuxの将来
私は、Linuxのカーネルをできるだけ小さくしようした我われの決定は確かに正しいものであったと思っている。また、正直なところ、私はカーネルを大幅にアップデートしようという考えを現時点では持ちあわせていない。成功するソフトウェア開発は、どこかで成熟期を迎え、それとともに、アップデートの速度も鈍化する。Linuxのカーネルに施すべき変更はもはやさほどない。現時点で我われが問題にすべきは、多岐にわたるシステムをどうサポートするかであろう。移植性の高さを利用して、どれだけ多くのシステムにLinuxを載せていくかである。
新たなインターフェイスも作られるだろうが、それは様々なアーキテクチャをサポートすることによって生まれてくるのだと思う。たとえば、クラスタリングの処理をしていると、突然スケジューラに、一定グループのプロセスに対してギャングスケジュールか何かを実行させたくなるときもある。しかし私はそう感じると同時に、誰もがクラスタリングやスーパーコンピューティングにばかりに目を向けるようなことにはなってほしくないと思ったりもする。というのも、コンピュータの未来は、ラップトップ型のコンピュータとともにあるのかもしれない。何にでもプラグインできるカードやそれに類したデバイスとともにあるのかもしれない。そう考える私は、Linuxにも未来のコンピュータとともに歩んでほしいと思っている。
それから、ユーザインターフェイスをまったく持たない組み込み用システムがある。組み込み用システムはただそこに置かれているだけである。システムにアクセスする必要があるのはカーネルをグレードアップするときだけという組み込み用システムは、Linuxの進むべき方向のひとつになると思う。Javaやインフェルノ(ルーセント・テクノロジーズ社の組み込み用OS)が組み込み用システムとして成功するとは思えない(ルーセント・テクノロジーズ社は、ベル研究所を傘下に治める、AT&Tから分離した会社)。この種の組み込み用システムは、開発に時間がかかりすぎてムーアの法則をうまく活用できない。特定のデバイスに合うように最適化した組み込み用システムを設計するという考えは、初めはいかにもよさそうに思える。しかし、それが完成するころには、ムーアの法則が働いて、より強力なハードウェアの価格が誰にでも手が届くところまで押し下げられてしまっている。そうなると、特定のデバイスに合うような組み込み用システムの価値はなくなってしまう。あらゆるものの値段が下がっているのだから、同じシステムを作るなら、組み込み用システムにするよりデスクトップ上で使えるものにするほうが開発も楽である。
シメトリックマルチプロセッシング(SMP、Symmetric Multi-Processing)も開発が進む分野のひとつだと思う。Linuxのバージョン2.2カーネルは、四つのプロセッサを十分活用できるようになっている。将来のバージョンでは、八個ないしは十六個のプロセッサを活用できるようにすることを考えている。五つ以上のプロセッサをサポートするシステムもすでに出回っているが、まだまだ実用的と言えるものではない。したがって五つ以上のプロセッサを搭載されているマシンの所有者は、金をドブに捨ててしまったようなものである。Linuxの開発が、この分野で進むことは間違いない。
なお、六十四個のプロセッサを搭載したマシン上でLinuxを使いたい人は、特別仕様のカーネルを使うことになるだろう。それだけのことを通常のカーネルでサポートしてしまうと、処理速度が遅くなって一般ユーザの使用に際して悪影響が出てしまう。
ある特定分野のアプリケーションをサポートするためにも、カーネルの開発は引き続き進められるだろう。ウェブサーバの機能は、カーネルへの依存度が実に大きいので、以前から私が興味を抱いていたことのひとつである。ある意味で、ウェブサーバの機能は私が深入りする危険をともなったものである。というのは、私のもとには、Linux上でウェブサーバを利用している人たちからのフィードバックが大量に送られてくるからである。そして、私もついついその気になって、ウェブサーバに合わせてLinuxを最適化しようと思ってしまったりするからである。ウェブサーバは重要なアプリケーションではあるが、それがすべてではないということを、私は心にとどめておかなければならない。
もちろん、今現在でもウェブサーバは、Linuxの潜在能力を完全に使いこなしてはいない。たとえば、Apacheもスレッドに関しては正しい使い方をしていない。
これまでのところ、この種の最適化は、ネットワークの帯域幅に限界があるため、なかなか進まなかった。10メガビットのネットワークはトラフィックがすぐに飽和状態になってしまうので、Linuxのウェブサーバ機能をこれ以上最適化してもしかたがない。10メガビットのネットワークを飽和させない唯一の方法は、強力なCGIをいくつもいくつも持つことであるが、それはカーネルですることではない。カーネルができることは、静的なHTMLページへのアクセスを直接処理し、もっと複雑な処理をApacheに依頼することである。より速いネットワークがもっと普及すれば、こうした機能にも関心が高まるだろう。しかし、いまのところ我われは、その種の実験をしたり開発を進めるに足るだけのハードウェアを十分所有していない。
将来起こりうるLinuxの未来像をこうして見てきたわけだが、私の希望は、Linuxにはこれからも最先端の技術を盛り込みたいということである。それもできれば、Linuxには最先端からもう一歩ぬきんでたところにいてほしい。デスクトップの明日は、今現在の最先端技術の向こうにあると思うからだ。
しかし、将来のLinuxの開発の中でもっともおもしろい変貌は、カーネル空間ではなく、ユーザ空間でこれから起こるのだろう。それに比べれば、カーネルの変貌はほんのわずかなものである。そう考えると、Linuxのカーネルが将来どのようになっているかは、それほどおもしろい問題ではない。それよりも、今から二、三年後にリリースされるであろうRed Hat17.5やWine(ウィンドウズのエミュレータ)がどんなものになるかに思いをめぐらすほうがもっとおもしろい。
今から十五年もたてば、誰かがこんなことを言うのではないかと思う。おい、僕はLinuxのやることなら何でもできるぞ。しかも、僕のシステムには二十年分のお荷物なんてないから、同じことをLinuxよりスリムに速くできる。Linuxは386のために設計されたが、新しいCPUを使えば、本当に面白いことを違ったやり方でできる。Linuxみたいな古いOSを使うのはもうよそう、と。私は、まさに同じことを言って、Linuxを作りはじめた。そして将来、人びとがLinuxのコードを調べ、Linuxのインターフェイスを使い、Linuxとバイナリ互換のシステムを我われに提供してくれる日が来たら、私は本当にうれしい。