kwkw @ ウィキ

Linuxカーネル

OSの構成要素のうち、メモリ管理プロセス管理デバイス管理など、コアとなる機能を提供する部分をカーネルという。
本頁では、Linuxを構成するカーネル(Linuxカーネル)について、特徴や利用の方法について述べる。


特徴

開発の背景 ~UNIXライクなOS~

1969年、AT&Tにて、UNIXと呼ばれるOSが開発された。
AT&Tは当初独占禁止法の問題を抱えていたため、このOSのソースコードを無償で配布した。C言語というアイデアにより移植性が高いため、大学や研究所などの教育機関で大規模な採用が行われたが、のちにAT&Tはライセンスによる制限を与えた。
広く普及したUNIXを代替する無償のOSへの需要は高く、様々な派生OS(これをUNIXライクなOSという)を生み出される。しかしこれらは、著作権の問題がなかなか解決されなかった。
この時期、オランダ・アムステルダム自由大学にてアンドリュー・タネンバウムの下、OSを学んでいた学生リーナス・トーバルスは、講義で利用したMinixと呼ばれるOSを参考にUNIXのコードを一切利用していないUNIXライクなOSを開発した。普及の進んでいたインターネットを通じて無償で公開され、瞬く間に注目を集める。これがのちの、Linuxカーネルである。

設計思想 ~マイクロカーネル~

カーネルには、先述したOSが担うべき機能を同一のメモリ空間内で実装すべきであるというモノリシックカーネルと、カーネルが持つべき機能を最低限に抑え資源の抽象化を行うべきであるというマイクロカーネルの2つの設計思想に大別される。Linuxは比較的モダンな後者のアイデアを採用しているが、UNIXはこれに対し前者のアイデアを採用していた。どちらも一長一短であり、「アンドリュー・タネンバウムとリーヌス・トーヴァルズの議論」にてこれについては議論されている。

開発スタイル ~バザール方式~

UNIXライクなOSである点に着目され多くの注目集めたLinuxカーネルであるが、その開発手法についても大きな注目が集まった。
UNIXライクなOSへ需要が高まっていた時期、FSFのリチャード・ストールマンも無償のカーネルを開発していたが難航している状況にあった。彼は、これまであたりまえのように行われてきた、外部にバグを隠しウォータフォールによる慎重に積み上げるような開発スタイルを行っていた。
同時期、リーナス・トーバルスは普及しつつあったインターネットにより世界中の多くの開発者とコミュニケーションを行い、先述した開発スタイルとは全く正反対の方法で、巨大なカーネルプログラムを完成させた。
これら2つのケース(開発手法)について分析され、1997年エリック・レイモンドによって、論文「伽藍とバザール」として発表された。
「はやめにリリース、しょっちゅうリリース」という考えで、プログラマやテスタがコミュニティを形成しプログラムを完成させるそのスタイルを比喩し、バザール方式と名付けた。その後、Mozillaプロジェクトの成功を受け、ビジネスからも注目が集まった。

ライセンス ~オープンソースソフトウェア~

先述した通り、FSFのリチャード・ストールマンはUNIXライクなOSの開発に失敗していた。自身の提唱するフリーソフトウェアというアイデアが採用されたUNIXライクなOSを欲していた彼は、同時期インターネットを通じて注目を浴びていたLinuxにその代わりを託したいと考えた。Linuxは彼の開発したフリーソフトウェアであるGNUのgccを用いていたため、この提案は行いやすい状況にあったからである。
Linuxは、その開発手法から、「無償でソースコードを公開する」という著作権上の要件を満たすため、パブリックドメイン化(著作権の破棄)を行う必要がある。しかし、パブリックドメインで公開されたソースコードは、第三者による独占化などのリスクも多く、この開発手法には不向きであった。リチャードの発明したフリーソフトウェアライセンスを適用すれば、このリスクを回避できる。このため、Linuxへこのライセンスの適用は、ごく自然なものであった。
その後、先述した論文「伽藍とバザール」によって、バザール方式開発と共にこのフリーソフトウェアライセンスも有名なものとなった。
論文の作者であるエリックは、この開発手法をビジネス界へ普及させるマーケティング手段として、これら開発手法・ライセンス体系に対して「オープンソース」という名称を与えた。このような背景もあり、Linuxはオープンソースの代表と呼ばれることが多い。
しかし、ライセンスという手段を、あくまでバザール方式開発で起こりうるリスクを低減するための目的に用いているリーナス側と、自身の「ソースコードは無償であるべき」という思想を支えることを目的とするリチャード側では、開発手法の考え方・ソースコードやソフトウェアのあり方・考えに大きな溝が存在する。リチャードは、「フリーソフトウェア」という言葉と、「オープンソース」という言葉を同一視することを拒否しており、Linuxはフリーソフトウェアライセンスを採用はしているものの、フリーソフトウェアとは言い難い。しかしながら、オープンソースという言葉はマーケティングとして成功しているため、フリーソフトウェアをオープンソースと呼ぶことも少なくない。

このような背景により、Linuxカーネルは、オープンソースライセンスでありフリーソフトウェアライセンスの一種である、GPLによって配布されている。


利用

バージョン

Linuxカーネルのバージョンは、開発手法が独特であるため、その扱い方に若干の癖がある。
カーネルを管理する際には、十分なテストが行われ安定して動作することを保証するものと、実験段階などにより安定していないものを区別する必要がある。

現在(2009年10月時点)は、「A.B.CD」と表記する。
Aは、メジャーバージョン番号と呼ばれ、コード全体が前バージョンとは全く異なる新しいものによって構成された場合に増加する。現在の2.0は、1996年5月に公開された。
Bは、マイナーバージョン番号と呼ばれ、かつてはコードが安定版か開発版かを判断するのに用いた。この番号が偶数の場合は安定版カーネル、奇数の場合は開発版カーネルとすることで区別し、Cではそれらのリビジョン番号として修正が入る都度増加するようになっていた。
しかし、2.6からコード数の増大によりこの法則は崩れた。2.6.11以降より、Dの4番目のリビジョン番号を持たせることで対処している。
Dが「.数字」の場合、安定版を表している。この数字は公開される都度増加する。
Dが「-rc数字」の場合、リリース候補と呼ばれ、次回の安定版の候補である事を表している。
Dが「-git数字」の場合、実験的なリリースであることを表し、試験的に機能を実装している事を表している。

カーネルに含まれる機能はバージョンによって判断が可能である。
これを確認するには、以下の3つの方法がある。

1. unameコマンド
unameコマンドは「Unix Name」の略であり、実行中のOSの名称やバージョン、ハードウェアアーキテクチャ等の情報を出力する。
名称の通り、UNIX専用のプログラムであるが、Linux上でも動作しており移植性は高い。
# uname -r
2.6.23.17-88.fc7
実行結果から、このカーネルはリリース候補であることが理解できる。

2. /proc/version
/procファイルシステムは本来、プロセスに対する操作をファイルという抽象的なインタフェースに操作するためのものであった。
現在は、物理的なファイルやデバイスに見えないようなものを、ファイルとして抽象化する領域として用いられている。
ここに置かれたversionファイルを参照することで、動作中のカーネルのバージョンを確認できる。
# cat /proc/version
Linux version 2.6.23.17-88.fc7 (mockbuild@xenbuilder2.fedora.redhat.com) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-27)) #1 SMP Thu May 15 00:35:10 EDT 2008

3. カーネルソースコードのMakefile
カーネルを一からコンパイルして利用している場合は、ソースコードが存在するため、これをチェックすることで確認が可能である。
Makefileにはコンフィギュレーションを設定するため、これを直接参照する。
# head -4 /usr/src/linux/Makefile
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 23
EXTRAVERSION = .17-88.fc7

カーネルイメージ

カーネルイメージとは、カーネルのバイナリデータのことであり、ファイルシステム上に置かれている。
ブートローダはディスクをファイルシステムとして認識した上で、指定した場所に置かれたカーネルイメージをメモリ上へロードする。
この場所は、一般的に以下の名称となる。
# ls /boot/vmlinuz*
/boot/vmlinuz-2.6.21-1.3228.fc7  /boot/vmlinuz-2.6.23.17-88.fc7  /boot/vmlinuz-2.6.21-7.fc7xen 
「vmlinuz-バージョン」となっており、この中から任意のカーネルを選択する。

カーネルは巨大なプログラムであるため、そのサイズは非常に大きい。
解凍は、ブートローダの機能でなければ、カーネル側の機能でもない。圧縮されたカーネルイメージはあたかも自己展開型形式ファイルのように自身を解凍し、指定のポイントからカーネルプログラムの実行を開始する。この流れは、以下のイメージである。

1.BIOSプログラムの実行(ブートローダのロード)
 ↓制御を渡す
2.ブートローダの実行(圧縮されたカーネルイメージのロード)
 ↓制御を渡す
3.自身の解凍処理の実行(解凍後のカーネルイメージのロード)
 ↓制御を渡す
4.カーネルプログラムの実行

一般的なOSの場合、カーネルプログラムの実行開始時には必ず様々な初期化処理が走る。具体的には、スタック領域の初期化やメモリレイアウトの構成、割り込みベクタを整理等である。
しかし、インテルアーキテクチャなどのCPUの場合、過去の命令・メモリとの互換性を保つため、起動時はリアル・モードで起動される。したがって、カーネルプログラムの実行開始時には、これら初期化処理の前に、プロテクト・モードへ切替えを行い、拡張された命令やメモリ空間へのアクセスが行えるように設定を行う必要がある。

カーネルイメージの解凍処理は、この切替処理が実行される前に実施される。このため、「リアル・モード」のままで動作する。
リアル・モードは、i8088プロセッサと同様の振る舞いをサポートするため、最大1Mのメモリ空間でしか活動が行えない。ビデオメモリを配慮すると、さらに小さな領域しか扱えなくなるため、圧縮されたカーネルイメージが512Kバイト以下で収まることを前提に設計を行う必要があった。しかし、近年カーネルは様々な機能をサポートし肥大化したため、このサイズには収める事ができなくなった。そこで、拡張BIOS命令を用いて、この制限を解除して解凍処理が行えるような方法も考えられた。前者はzImage、後者はbzImageと呼ばれる。

拡張BIOS命令は、全ての環境でサポートされるわけではないので、zImageのニーズは0ではない。
しかし、近年のカーネルイメージのサイズはどれだけ削っても512Kバイトに収まることは難しいため、bzImageが主流である。