次のページ 前のページ 目次へ

15. Linux カーネルソース

この章では、特定のカーネル関数を見たいとき、カーネルソースのどこから 探し始めればよいのかについて説明する。

本書は、C プログラミング言語の知識を前提とするものではなく、カーネルの動作 の仕組みを理解するのに Linux カーネルソースを持っていることを要求するものでも ない。とはいえ、カーネルソースを見て、Linux オペレーティングシステムへの理解を 深める努力をすることはよい結果をもたらすことだろう。この章では、カーネルソース の概観を説明し、それらの構造や特定のコードを探す時の目安となるものについて 述べる。

15.1 Linux カーネルソースの入手場所

メジャーな Linux ディストリビューション( Craftworks, Debian, Slackware, Red Hat などなど)ならどこでも、カーネルソースが同梱されている。通常、システム にインストールされた Linux カーネルは、そうしたソースからビルドされている。 やむを得ない事情から、それらのソースは少々古いものになりがちなので、 「ウェブと FTP サイト」で述べるウェブサイト から最新のソースを入手したいと考えるかもしれない。ソースコードは、 ftp://ftp.cs.helsinki.fi で保存されていて、それ以外のウェブサイトはすべてそのミラーである。 (訳注: 現在のプライマリサイトは、 http://www.kernel.org です。) それゆえ、Helsinki のウェブサイトに最新のソースがあることになるが、MIT や Sunsite でも決してひどく古いわけではない。

ウェブにアクセスできない場合でも、多くの CD-ROM ベンダがあり、それらが 世界のメジャーなウェブサイトのスナップショットを妥当な値段で提供している。 四半期や、あるいは毎月更新される定期購買サービスを提供しているベンダまである。 ローカルな Linux ユーザグループも、ソースコードの提供元である。

Linux カーネルソースは、非常にシンプルなバージョン番号管理をしている。 中央の番号、x.y.zy が、偶数番号のカーネル(たとえば、 2.0.30)は、安定した、リリース版カーネルで、奇数番号のカーネル(たとえば、2.1.42) は、開発版カーネルである。本書は、安定版 2.0.30 のソースツリーに基づいている。 開発版カーネルは最新機能のすべてを備え、最新デバイスをすべて サポートしている。それらは安定しない場合があるかもしれず、それはあなたが Linux に求めるものではないかもしれないが、Linux コミュニティーが最新版 カーネルを試しているということは重要である。それによって、最新版は コミュニティー全体でテストされるからである。安定版でないカーネルを使う場合、 システム全体のバックアップは常に価値あるものであることを忘れないでほしい。

カーネルソースへの変更は、パッチファイルで配布される。パッチユーティリティ は、ソースファイルのセットに一連の編集を加えるために使用される。たとえば、 2.0.29 のカーネルソースツリーを持っていて、2.0.30 のソースツリーに移行したい 場合は、2.0.30 のパッチを入手して、そのパッチ(ソース編集スクリプト)をその カーネルソースに適用すればよい。

$ cd /usr/src/linux
$ patch -p1 < patch-2.0.30

そうすれば、ソースツリー全体を、おそらく低速なシリアル回線を使ってコピーしな くても済む。カーネルパッチ(正式版もそうでないものも)の便利な入手先は、 http://www.linuxhq.web.site である。

15.2 カーネルソースの構造

ソースツリーの最上ディレクトリである /usr/src/linux には、 (次のような)多くのディレクトリがある。

<#if output="html">

(訳注: JF サイト上でご覧の場合、一部のファイルしか表示されません。 ソース全体を見るには、 日本語訳についてを参照してください。) <#/if>

arch

arch サブディレクトリには、アーキテクチャ(architecture)固有の カーネルコードが含まれている。 さらに深いサブディレクトリがあり、たとえば、i386 や alpha と いったサポートするアーキテクチャごとに分かれている。

include

include サブディレクトリには、カーネルコードをビルドするのに必要な インクルードファイル(include files)の大部分が含まれている。 さらに深いサブディレクトリもあり、サポートするアーキテクチャごとのファイルが含 まれている。include/asm サブディレクトリは、たとえば include/asm-i386 といったそのアーキテクチャに必要な実際の include ディレクトリへのソフトリンク(シンボリックリンク)となっている。 アーキテクチャを変更するには、カーネルの makefile を編集し、Linux カーネル 設定プログラムを再実行する必要がある。

init

このディレクトリには、カーネルの初期化(initialization)コードが含まれているの で、カーネルの動作の仕組みをこれから見ようとする場合はよい出発点になる。

mm

このディレクトリには、メモリ管理(memory management)コードのすべてが含まれてい る。アーキテクチャ固有のメモリ管理コードについては、arch/i386/mm/fault.c といった arch/*/mm ディレクトリ以下にある。

drivers

システム上のデバイスドライバ(device drivers)は、すべてこのディレクトリに置かれ ている。 このディレクトリはさらに再分割され、block といったデバイスドライバ のクラスごとに分かれている。

ipc

このディレクトリには、カーネルのプロセス間通信(inter-process communications)に 関するコードが含まれている。

modules

このディレクトリは、ビルドされたモジュール(module)を保存するためだけに使用され ている。

fs

ファイルシステム(file system)コードのすべてはここに置かれている。 このディレクトリはさらに再分割されていて、vfatext2 と いったサポートするファイルシステムごとに分かれている。

kernel

主要なカーネル(kernel)コードが置かれている。ここでも、アーキテクチャ固有の カーネルコードは、arch/*/kernel にある。

net

カーネルのネットワーク(network)関係のコードが置かれている。

lib

このディレクトリには、カーネルのライブラリ(library)コードが含まれている。 アーキテクチャ固有のライブラリは、arch/*/lib で見つけることができる。

scripts

このディレクトリには、カーネルを設定するときに使用されるスクリプト(script) (たとえば、awktk スクリプト)が含まれている。

15.3 どこから見るべきか

Linux カーネルくらい巨大で複雑なプログラムになると、見ようとする者を威圧 するかのような感がなくもない。まるで辿るべき一端がなくて、解けない球状の 巻き糸のようである。カーネルの一部を見ていると、しばしばいくつかの他の関連 ファイルへと導かれて、すぐに自分で何を探していたのか分からなくなる。以下では、 節に付けた題名について、ソースツリーのどこを見れば最良かヒントを述べる。

システムの起動と初期化

Intel ベースのシステムなら、カーネルが起動するのは、loadlin.exe か LILO がカーネルをメモリにロードして制御をカーネルに渡したときである。 その部分に関しては、 arch/i386/kernel/head.S を見ること。head.S はアーキテクチャ固有の設定をいくつか行ってから、 init/main.c 内にある main() ルーチンへジャンプする。

メモリ管理

これに関するコードの大部分は mm にあるが、アーキテクチャ固有の コードは arch/*/mm にある。ページフォルト処理コードは mm/memory.c にあり、メモリマッピングとページキャッシュのコードは mm/filemap.c にある。 バッファキャッシュは、mm/buffer.c(訳注: fs/buffer.c) で実装されており、 スワップキャッシュは mm/swap_state.c mm/swapfile.c にある。

カーネル

関連する汎用コードの大部分は、kernel にあるが、アーキテクチャ固有 のコードは arch/*/kernel にある。スケジューラは kernel/sched.c にあり、fork のコードは kernel/fork.c にある。 ボトムハーフ処理のコードは include/linux/interrupt.h に含まれている。 task_struct データ構造体は、 include/linux/sched.h にある。

PCI

PCI 仮想ドライバは drivers/pci/pci.c にあり、システム全体の定義 は include/linux/pci.h にある。個々のアーキテクチャには固有の PCI BIOS コードがあり、Alpha AXP のものは arch/alpha/kernel/bios32.c にある。

プロセス間通信

これらはすべて ipc にある。すべての System V IPC オブジェクトは ipc_perm データ構造体を含んでいるが、これは include/linux/ipc.h にある。System V メッセージは ipc/msg.c で実装されていて、 共有メモリは ipc/shm.c 、セマフォは ipc/sem.c にある。 パイプは、ipc/pipe(訳注: fs/pipe.c) で実装されている。

割り込み処理

カーネルの割り込み処理コードは、ほとんどすべてマイクロプロセッサ(そして、 しばしばプラットフォーム)固有のものである。Intel の割り込み処理コードは、 arch/i386/kernel/irq.c にあり、その定義は include/asm-i386/irq.h にある。

デバイスドライバ

Linux カーネルソースコードの大部分は、デバイスドライバのものである。 Linux デバイスドライバのソースのすべては、drivers にあるが、その ディレクトリはデバイスタイプによってさらに分岐している。

/block

IDE( ide.c) などのブロックデバイスドライバ。ファイルシステムを置くことができる すべてのデバイスがどのように初期化されるのかを見たい場合は、 drivers/block/genhd.c にある device_setup() を見るべき である。 それは、ハードディスクの初期化だけでなく、NFS ファイルシステムをマウントする ためにネットワークを必要とする際にはネットワークデバイスをも初期化する。 ブロックデバイスには、IDE ベースと SCSI ベースの両方のデバイスが含まれる。

/char

ここは、tty やシリアルポート、マウスなどのキャラクタベースのデバイスを 探すときに見る場所である。

/cdrom

Linux 上のすべての CD-ROM のコード。特定の CD-ROM デバイス(たとえば、 Soundblaster CD-ROM)がここに置かれている。IDE CD ドライバは drivers/block ide-cd.c にあり、SCSI CD ドライバは drivers/scsi scsi.c にあるので、注意すること。

/pci

ここには、PCI 仮想ドライバのためのソースがある。PCI サブシステムがマップされ 初期化される方法を見るのに適した場所である。 arch/alpha/kernel/bios32.c にある Alpha AXP PCI 修正(fixup)コード も見るに値するだろう。

/scsi

ここは、SCSI コードのすべてがある場所であり、Linux でサポートされている SCSI デバイスのすべてのドライバが置かれている場所である。

/net

ここは、DEC Chip 21040 PCI イーサネットドライバ( tulip.c)といったネットワークデバイスドライバが見つかる場所である。

/sound

ここは、すべてのサウンドカードドライバがある場所である。

ファイルシステム

EXT2 ファイルシステムのソースはすべて、fs/ext2 ディレクトリにあり、 データ構造の定義は、 include/linux/ext2_fs.h ext2_fs_i.h, ext2_fs_sb.h にある。 仮想ファイルシステムのデータ構造体は、 include/linux/fs.h に記述されており、そのコードは fs/* に ある。バッファキャッシュは、update デーモンと一緒に fs/buffer.c で実装されている。

ネットワーク

ネットワークのコードは、net に保存されていて、その大部分の include ファイルは include/net にある。BSD ソケットコードは、 net/socket.c にあり、IP version 4 INET ソケットコードは、 net/ipv4/af_inet.c にある。 汎用のプロトコルサポートコード(sk_buff 処理ルーチンなど)は、 net/core にあり、TCP/IP ネットワークのコードは net/ipv4 にある。ネットワークデバイスドライバは、drivers/net にある。

モジュール

カーネルモジュールコードは、カーネル内にある部分とその modules の パッケージに入っている部分とがある。カーネルコードはすべて kernel/module.c にあり、 そのデータ構造とカーネルデーモンである kerneld の メッセージは、 include/linux/module.h include/linux/kerneld.h とにそれぞれ入っている。 ELF オブジェクトファイルの構造は、 include/linux/elf.h で見ることができる。


次のページ 前のページ 目次へ