1. まとめトップ

この記事は私がまとめました

twcritiqueさん

コードはここのを見る

物理的なソースから入る

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)コードのすべてはここに置かれている。 このディレクトリはさらに再分割されていて、vfat や ext2 と いったサポートするファイルシステムごとに分かれている。

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

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

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

scripts
このディレクトリには、カーネルを設定するときに使用されるスクリプト(script) (たとえば、awk や tk スクリプト)が含まれている。
http://archive.linux.or.jp/JF/JFdocs/The-Linux-Kernel-15.html#ss15.1

カーネルのソース・コードでは、あらゆる場所でデータの構造を定義した「構造体」が使われています。

構造体の読み方をマスターすればカーネル・ソースが一段と理解しやすくなります。今回は、「構造体とは何か」と「なぜカーネルが構造体を駆使するのか」を解説します。

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
ここは、すべてのサウンドカードドライバがある場所である。

概念から入る

上部にあるのはユーザー (つまりアプリケーション) 空間です。ユーザー・アプリケーションはここで実行されます。ユーザー空間の下にあるのはカーネルで、ここが Linux カーネルが存在する場所です。

ここでプログラムがデータを処理し、ファイルにデータを書き込む時を考えてみましょう。

ユーザ空間でデータが処理され、write(2)でファイルに書込にいきます。すると、制御は一旦カーネル空間に移ります。カーネルでの処理が済んで、またユーザ空間に戻ってきます。このようにカーネルはユーザ空間で動くプログラムの制御と、カーネル内での必要な資源の提供と管理を行っています。以下に単純化したモデルを示してみます。

機能から見ていく

プロセス管理
プロセス生成・消滅
スケジュラ

ファイルシステム
名前空間管理
VFS
ext2, etc3, JFS, ReiserFS, XFS, ISO9660...
ネットワークファイルシステム
デバイスファイル

プロセス間通信
セマフォ
メッセージキュー
パイプ, fifo (named pipe)

記憶管理
ページ管理
バーチャルメモリ (swap)
mmap
シェアードメモリ

ネットワーク
IPスタック (TCP/UDP/ICMP/..)
その他プロトコル

デバイスドライバ
仮想デバイス
各種I/Oドライバ
http://uc.h2np.net/index.php/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%81%AE%E6%A7%8B%E9%80%A0%E3%81%A8%E6%A9%9F%E8%83%BD

アプローチを考える

カーネル・ソースの読解が難しい理由の一つは「構造体の多用」にあります。構造体は、複数の種類のデータをまとめるものですが、カーネルでは、関数の先頭番地を登録する手法が多く見られます。この手法を使えば、モジュールを簡単に差し替えられます。デバイス・ドライバを例に、その様子を見ていきましょう。

パーティションテーブルの構造は、FreeBSD のカーネルソースに構造体の定義があるので参考にする。(FreeBSD は PC-98 対応版が 2008 年頃までリリースされていたため、PC-98 用のコードが残っている。)

Linux のコンソールからの入力行を編集するには,単に標準入力から 取り込むだけでは実現できません.キーボードから入力する文字のうち カーソルを移動したり,文字の削除などに使うキー入力は表示する必要 がありません.またカーソルを移動するための方法も必要になります. このようにコンソールに対する入力を制御するために termios という 機能を使い,エスケープシーケンスと呼ぶ画面出力をコントロール するための特定の文字列を使用する必要があります. termios とエスケープシーケンスには非常に豊富な機能がありますが, ここでは行編集に使う部分だけを解説します.

1