詳解 Linuxカーネル 第3版

[cover photo]
  • 2007年02月 発行
  • 1024ページ
  • ISBN978-4-87311-313-5
  • フォーマット Print PDF
  • 原書: Understanding the Linux Kernel, 3rd Edition

オライリー・ジャパンで書籍を購入:
定価7,128円

Ebook Storeで電子版を購入:
価格5,702円

本書はLinuxのソースコードの恩恵を最大限に活かすための羅針盤です。複雑で難解なLinuxカーネルの仕組みを、基礎からていねいに説明。Linuxカーネルの基本機能を網羅し、ハードウェア依存部分についても踏み込んだ解説がなされています。第3版では、Linux 2.6を対象として改訂を行い、特にメモリとプロセススケジューリングについて大幅な変更と加筆がなされています。Linuxのソースコードを理解するためのガイドブックとして、オペレーティングシステムの本格的な解説書として最適の1冊です。

関連書籍

Debug Hacks
Linuxカーネル Hacks
Linuxカーネル クイックリファレンス
Linuxサーバ Hacks
Linuxサーバ Hacks 2
Linuxシステムプログラミング
Linuxデバイスドライバ 第3版
Linuxプログラミングインタフェース
詳解 システム・パフォーマンス

監訳者まえがき
はじめに

1章 概要
	1.1 LinuxとほかのUNIX系カーネル
	1.2 ハードウェア依存
	1.3 Linuxのバージョン
	1.4 オペレーティングシステムの基本概念
		1.4.1 マルチユーザシステム
		1.4.2 ユーザとグループ
		1.4.3 プロセス
		1.4.4 カーネルアーキテクチャ
	1.5 UNIXファイルシステムの概要
		1.5.1 ファイル
		1.5.2 ハードリンクとソフトリンク
		1.5.3 ファイルの種類
		1.5.4 ファイルディスクリプタとiノード
		1.5.5 アクセス権とファイルのモード
		1.5.6 ファイルを取り扱うシステムコール
	1.6 UNIXカーネルの概要
		1.6.1 プロセス/カーネルモデル
		1.6.2 プロセスの実装
		1.6.3 再入可能なカーネル
		1.6.4 プロセスアドレス空間
		1.6.5 同期とクリティカル区間
		1.6.6 シグナルとプロセス間通信
		1.6.7 プロセス管理
		1.6.8 メモリ管理
		1.6.9 デバイスドライバ

2章 メモリアドレッシング
	2.1 メモリアドレス
	2.2 ハードウェアのセグメント機構
		2.2.1 セグメントセレクタとセグメントレジスタ
		2.2.2 セグメントディスクリプタ
		2.2.3 セグメントディスクリプタへの高速アクセス
		2.2.4 セグメンテーション回路
	2.3 Linuxのセグメント機構
		2.3.1 LinuxのGDT
		2.3.2 LinuxのLDT
	2.4 ハードウェアのページング機構
		2.4.1 通常のページング
		2.4.2 拡張ページング
		2.4.3 ハードウェア保護機構
		2.4.4 通常ページングの例
		2.4.5 物理アドレス拡張ページング機構
		2.4.6 64ビットアーキテクチャにおけるページング
		2.4.7 ハードウェアキャッシュ
		2.4.8 アドレス変換バッファ(TLB)
	2.5 Linuxのページング機構
		2.5.1 リニアアドレスフィールド
		2.5.2 ページテーブルの処理
		2.5.3 物理メモリレイアウト
		2.5.4 プロセスのページテーブル
		2.5.5 カーネルのページテーブル
		2.5.6 固定マップ用リニアアドレス
		2.5.7 ハードウェアキャッシュとTLBの制御

3章 プロセス
	3.1 プロセス、軽量プロセス、スレッド
	3.2 プロセスディスクリプタ
		3.2.1 プロセスの状態
		3.2.2 プロセスの識別
		3.2.3 プロセスの親子関係
		3.2.4 プロセスの管理方法
		3.2.5 プロセスの資源利用制限
	3.3 プロセス切り替え
		3.3.1 ハードウェアコンテキスト
		3.3.2 タスク状態セグメント
		3.3.3 プロセス切り替えの実行
		3.3.4 FPUレジスタ、MMXレジスタ、XMMレジスタの退避回復
	3.4 プロセスの生成
		3.4.1 clone()、fork()、vfork()システムコール
		3.4.2 カーネルスレッド
	3.5 プロセスの破棄
		3.5.1 プロセスの終了
		3.5.2 プロセスの削除

4章 割り込みと例外
	4.1 割り込み信号の役割
	4.2 割り込みと例外
		4.2.1 IRQと割り込み
		4.2.2 例外
		4.2.3 割り込みディスクリプタテーブル
		4.2.4 ハードウェアの割り込みと例外の処理
	4.3 例外および割り込み処理のネスト
	4.4 割り込みディスクリプタテーブルの初期化
		4.4.1 割り込み、トラップ、システムゲート
		4.4.2 IDTの予備初期化
	4.5 例外処理
		4.5.1 例外ハンドラ用のレジスタ退避処理
		4.5.2 例外ハンドラの開始と終了
	4.6 割り込み処理
		4.6.1 I/O割り込み処理
		4.6.2 プロセッサ間割り込み処理
	4.7 ソフト割り込みとタスクレット
		4.7.1 ソフト割り込み
		4.7.2 タスクレット
	4.8 ワークキュー
	4.9 割り込みおよび例外からの復帰

5章 カーネルの同期処理
	5.1 カーネルは要求をどのように処理するか
		5.1.1 カーネル内プリエンプション
		5.1.2 同期の必要がある場合
		5.1.3 同期の必要がない場合
	5.2 同期プリミティブ
		5.2.1 CPUごとの変数
		5.2.2 アトミック操作(不可分操作)
		5.2.3 最適化処理とメモリバリア
		5.2.4 スピンロック
		5.2.5 読み書き用スピンロック
		5.2.6 順次ロック
		5.2.7 Read-Copy Update(RCU)
		5.2.8 セマフォ
		5.2.9 読み書き用セマフォ
		5.2.10 完了通知
		5.2.11 ローカル割り込み禁止
		5.2.12 遅延処理の禁止と許可
	5.3 カーネルデータアクセスの同期
		5.3.1 スピンロック、セマフォおよび割り込み禁止の選択
	5.4 競合状態回避の例
		5.4.1 参照カウンタ
		5.4.2 ビッグカーネルロック
		5.4.3 メモリディスクリプタの読み書き用セマフォ
		5.4.4 スラブキャッシュリストのセマフォ
		5.4.5 iノードのセマフォ

6章 時間管理
	6.1 クロック回路とタイマ回路
		6.1.1 リアルタイムクロック(RTC)
		6.1.2 タイムスタンプカウンタ(TSC)
		6.1.3 プログラマブルインターバルタイマ(PIT)
		6.1.4 CPUローカルタイマ
		6.1.5 高精度イベントタイマ(HPET)
		6.1.6 ACPI電源管理タイマ(ACPI PMT)
	6.2 時間管理の仕組み
		6.2.1 時間管理のデータ構造
		6.2.2 単一プロセッサシステムにおける時間管理の仕組み
		6.2.3 マルチプロセッサシステムにおける時間管理の仕組み
	6.3 時刻と日付の更新
	6.4 統計情報の更新
		6.4.1 ローカルCPUの統計情報の更新
		6.4.2 システム負荷の管理
		6.4.3 カーネルコードのプロファイリング
		6.4.4 NMIウォッチドッグの確認
	6.5 ソフトウェアタイマと遅延関数
		6.5.1 動的タイマ
		6.5.2 動的タイマの適用例:nanosleep()システムコール
		6.5.3 遅延関数
	6.6 時間管理関連のシステムコール
		6.6.1 time()、gettimeofday()システムコール
		6.6.2 adjtimex()システムコール
		6.6.3 setitimer()、alarm()システムコール
		6.6.4 POSIXタイマ

7章 プロセススケジューリング
	7.1 スケジューリング方針
		7.1.1 プロセスプリエンプション
		7.1.2 最適なクォンタムの長さ
	7.2 スケジューリングアルゴリズム
		7.2.1 従来型プロセスのスケジュール
		7.2.2 リアルタイムプロセスのスケジュール
	7.3 スケジューラが使用するデータ構造
		7.3.1 runqueueデータ構造
		7.3.2 プロセスディスクリプタ
	7.4 スケジューラが使用する関数
		7.4.1 scheduler_tick()関数
		7.4.2 try_to_wake_up()関数
		7.4.3 recalc_task_prio()関数
		7.4.4 schedule()関数
	7.5 マルチプロセッサにおける実行キューの負荷均衡化処理
		7.5.1 スケジューリングドメイン
		7.5.2 rebalance_tick()関数
		7.5.3 load_balance()関数
		7.5.4 move_tasks()関数
	7.6 スケジューリング関連のシステムコール
		7.6.1 nice()システムコール
		7.6.2 getpriority()、setpriority()システムコール
		7.6.3 sched_getaffinity()、sched_setaffinity()システムコール
		7.6.4 リアルタイムプロセス関連のシステムコール

8章 メモリ管理
	8.1 ページフレームの管理
		8.1.1 ページディスクリプタ
		8.1.2 不均等メモリアクセスアーキテクチャ(NUMA)
		8.1.3 メモリゾーン
		8.1.4 空きページフレームの予約
		8.1.5 ゾーンごとのページフレームアロケータ
		8.1.6 高位メモリのページフレームのカーネルマッピング
		8.1.7 バディシステム
		8.1.8 CPUごとのページフレームキャッシュ
		8.1.9 ゾーンアロケータ
	8.2 メモリ領域の管理
		8.2.1 スラブアロケータ
		8.2.2 キャッシュディスクリプタ
		8.2.3 スラブディスクリプタ
		8.2.4 汎用キャッシュと特定用途のキャッシュ
		8.2.5 スラブアロケータとゾーンごとのページフレームアロケータ間のインタフェース
		8.2.6 キャッシュへのスラブの割り当て
		8.2.7 キャッシュからのスラブの解放
		8.2.8 オブジェクトディスクリプタ
		8.2.9 メモリ上でのオブジェクトの境界合わせ
		8.2.10 スラブの色付け
		8.2.11 空きスラブオブジェクトのローカルキャッシュ
		8.2.12 スラブオブジェクトの割り当て
		8.2.13 スラブオブジェクトの解放
		8.2.14 汎用オブジェクト
		8.2.15 メモリプール
	8.3 非連続メモリ領域の管理
		8.3.1 非連続メモリ領域のリニアアドレス
		8.3.2 非連続メモリ領域のディスクリプタ
		8.3.3 非連続メモリ領域の割り当て
		8.3.4 非連続メモリ領域の解放

9章 プロセスアドレス空間
	9.1 プロセスのアドレス空間
	9.2 メモリディスクリプタ
		9.2.1 カーネルスレッドのメモリディスクリプタ
	9.3 メモリリージョン
		9.3.1 メモリリージョンのデータ構造
		9.3.2 メモリリージョンのアクセス権
		9.3.3 メモリリージョン処理
		9.3.4 リニアアドレス区間の割り当て
		9.3.5 リニアアドレス区間の解放
	9.4 ページフォルト例外ハンドラ
		9.4.1 アドレス空間外の例外処理
		9.4.2 アドレス空間内の例外処理
		9.4.3 デマンドページング
		9.4.4 コピーオンライト
		9.4.5 非連続メモリ領域へのアクセス
	9.5 プロセスアドレス空間の生成と削除
		9.5.1 プロセスアドレス空間の生成
		9.5.2 プロセスアドレス空間の削除
	9.6 ヒープ領域の管理

10章 システムコール
	10.1 POSIX APIとシステムコール
	10.2 システムコールハンドラとシステムコールサービスルーチン
	10.3 システムコールの入口と出口
		10.3.1 int $0x80命令によるシステムコール発行
		10.3.2 sysenter命令によるシステムコール発行
	10.4 引数の受け渡し
		10.4.1 引数の確認
		10.4.2 プロセスアドレス空間へのアクセス
		10.4.3 アドレスの動的な確認とfixupコード
		10.4.4 例外テーブル
		10.4.5 例外テーブルとfixupコードの生成
	10.5 カーネルラッパールーチン

11章 シグナル
	11.1 シグナルの役割
		11.1.1 シグナル配信時の動作
		11.1.2 POSIXシグナルとマルチスレッドアプリケーション
		11.1.3 シグナル関連のデータ
		11.1.4 シグナル関連のデータの操作
	11.2 シグナルの生成
		11.2.1 specific_send_sig_info()関数
		11.2.2 send_signal()関数
		11.2.3 group_send_sig_info()関数
	11.3 シグナルの配信
		11.3.1 シグナルの標準設定動作の実行
		11.3.2 シグナルの捕捉
		11.3.3 システムコールの再実行
	11.4 シグナル処理関連のシステムコール
		11.4.1 kill()システムコール
		11.4.2 tkill()、tgkill()システムコール
		11.4.3 シグナル受信処理の変更
		11.4.4 ブロックされている保留中シグナルの確認
		11.4.5 ブロックするシグナルの変更
		11.4.6 プロセスの停止
		11.4.7 リアルタイムシグナル用のシステムコール

12章 仮想ファイルシステム(VFS)
	12.1 仮想ファイルシステム(VFS)の役割
		12.1.1 共通ファイルモデル
		12.1.2 VFSが取り扱うシステムコール
	12.2 VFSデータ構造
		12.2.1 スーパブロックオブジェクト
		12.2.2 iノードオブジェクト
		12.2.3 ファイルオブジェクト
		12.2.4 dエントリオブジェクト
		12.2.5 dエントリキャッシュ
		12.2.6 プロセスとファイル
	12.3 ファイルシステム種別
		12.3.1 特殊ファイルシステム
		12.3.2 ファイルシステム種別の登録
	12.4 ファイルシステムの操作
		12.4.1 名前空間
		12.4.2 ファイルシステムのマウント
		12.4.3 一般ファイルシステムのマウント
		12.4.4 ルートファイルシステムのマウント
		12.4.5 ファイルシステムのアンマウント
	12.5 パス名の検索
		12.5.1 標準的なパス名の検索
		12.5.2 親パス名の検索
		12.5.3 シンボリックリンクの検索
	12.6 VFSシステムコールの実装
		12.6.1 open()システムコール
		12.6.2 read()、write()システムコール
		12.6.3 close()システムコール
	12.7 ファイルロック
		12.7.1 Linuxのファイルロック
		12.7.2 ファイルロックデータ構造
		12.7.3 FL_FLOCKロック
		12.7.4 FL_POSIXロック

13章 I/Oデバイスの管理
	13.1 I/Oアーキテクチャ
		13.1.1 I/Oポート
		13.1.2 I/Oインタフェース
		13.1.3 デバイスコントローラ
	13.2 デバイスドライバモデル
		13.2.1 sysfsファイルシステム
		13.2.2 kオブジェクト
		13.2.3 デバイスドライバモデルの構成要素
	13.3 デバイスファイル
		13.3.1 デバイスファイルのユーザモード処理
		13.3.2 VFSのデバイスファイルの取り扱い
	13.4 デバイスドライバ
		13.4.1 デバイスドライバの登録
		13.4.2 デバイスドライバの初期化
		13.4.3 I/O操作の監視
		13.4.4 I/O共有メモリへのアクセス
		13.4.5 ダイレクトメモリアクセス(DMA)
		13.4.6 カーネルの支援水準
	13.5 キャラクタ型デバイスドライバ
		13.5.1 デバイス番号の割り当て
		13.5.2 キャラクタ型デバイスドライバへのアクセス
		13.5.3 キャラクタ型デバイスのバッファリング方式

14章 ブロック型デバイスドライバ
	14.1 ブロック型デバイスの管理
		14.1.1 セクタ
		14.1.2 ブロック
		14.1.3 セグメント
	14.2 汎用ブロック層
		14.2.1 bioデータ構造
		14.2.2 ディスクとディスクパーティションの管理方式
		14.2.3 要求の発行
	14.3 I/Oスケジューラ
		14.3.1 要求キューディスクリプタ
		14.3.2 要求ディスクリプタ
		14.3.3 ブロック型デバイスドライバの有効化
		14.3.4 I/Oスケジューリングアルゴリズム
		14.3.5 I/Oスケジューラに対する要求の発行
	14.4 ブロック型デバイスドライバ
		14.4.1 ブロック型デバイス
		14.4.2 デバイスドライバの登録と初期化
		14.4.3 ストラテジルーチン
		14.4.4 割り込みハンドラ
	14.5 ブロック型デバイスファイルのオープン

15章 ページキャッシュ
	15.1 ページキャッシュ
		15.1.1 アドレス空間オブジェクト
		15.1.2 基数ツリー
		15.1.3 ページキャッシュ操作関数
		15.1.4 基数ツリーのタグ
	15.2 ページキャッシュへのブロック格納
		15.2.1 ブロックバッファとバッファヘッド
		15.2.2 バッファヘッドの管理
		15.2.3 バッファページ
		15.2.4 ブロック型デバイスバッファページの確保
		15.2.5 ブロック型デバイスバッファページの解放
		15.2.6 ページキャッシュ内のブロック検索
		15.2.7 汎用ブロック層へのバッファヘッドの処理依頼
	15.3 汚れたページのディスクへの書き込み
		15.3.1 pdflushカーネルスレッド
		15.3.2 書き込み対象とする汚れたページの探索
		15.3.3 古い汚れたページの取り出し
	15.4 sync()、fsync()、fdatasync()システムコール
		15.4.1 sync()システムコール
		15.4.2 fsync()、fdatasync()システムコール

16章 ファイルアクセス
	16.1 ファイルの読み取りと書き込み
		16.1.1 ファイルの読み取り
		16.1.2 ファイルの先読み
		16.1.3 ファイルへの書き込み
		16.1.4 汚れたページのディスクへの書き込み
	16.2 メモリマッピング
		16.2.1 メモリマッピングのデータ構造
		16.2.2 メモリマッピングの生成
		16.2.3 メモリマッピングの削除
		16.2.4 メモリマッピングのデマンドページング
		16.2.5 メモリマッピングされた汚れたページのディスクへの書き込み
		16.2.6 非線形なメモリマッピング
	16.3 ダイレクトI/O転送
	16.4 非同期I/O
		16.4.1 Linux 2.6における非同期I/O

17章 ページフレームの回収
	17.1 ページフレーム回収アルゴリズム
		17.1.1 対象ページの選択
		17.1.2 ページフレーム回収アルゴリズムの設計
	17.2 逆マッピング
		17.2.1 無名ページの逆マッピング
		17.2.2 マッピングされたページの逆マッピング
	17.3 ページフレーム回収アルゴリズム(PFRA)の実装
		17.3.1 最長不使用順(LRU)リスト
		17.3.2 メモリ不足時の回収処理
		17.3.3 ディスクキャッシュからのページの回収
		17.3.4 定期的回収処理
		17.3.5 OOMキラー
		17.3.6 スワップ優先権
	17.4 スワップ処理
		17.4.1 スワップ領域
		17.4.2 スワップ領域ディスクリプタ
		17.4.3 スワップアウトページ識別子
		17.4.4 スワップ領域の有効化と無効化
		17.4.5 ページスロットの割り当てと解放
		17.4.6 スワップキャッシュ
		17.4.7 ページのスワップアウト
		17.4.8 ページのスワップイン

18章 Ext2、Ext3ファイルシステム
	18.1 Ext2の一般的な特徴
	18.2 Ext2ディスク上のデータ構造
		18.2.1 スーパブロック
		18.2.2 グループディスクリプタとビットマップ
		18.2.3 iノードテーブル
		18.2.4 iノードの拡張属性
		18.2.5 アクセス制御リスト(ACL)
		18.2.6 ファイル種類とディスクブロックの使用法
	18.3 Ext2メモリ上のデータ構造
		18.3.1 Ext2スーパブロックオブジェクト
		18.3.2 Ext2 iノードオブジェクト
	18.4 Ext2ファイルシステムの作成
	18.5 Ext2関数
		18.5.1 Ext2スーパブロック操作
		18.5.2 Ext2 iノード操作
		18.5.3 Ext2ファイル操作
	18.6 Ext2ディスク領域の管理
		18.6.1 iノードの作成
		18.6.2 iノードの削除
		18.6.3 データブロックのアドレッシング
		18.6.4 ファイルホール
		18.6.5 データブロックの割り当て
		18.6.6 データブロックの解放
	18.7 Ext3ファイルシステム
		18.7.1 ジャーナリングファイルシステム(JFS)
		18.7.2 Ext3ジャーナリングファイルシステム
		18.7.3 ジャーナリングブロック型デバイス(JBD)
		18.7.4 ジャーナリングの動作

19章 プロセス間通信
	19.1 パイプ
		19.1.1 パイプの利用
		19.1.2 パイプのデータ構造
		19.1.3 パイプの作成と削除
		19.1.4 パイプからの読み込み
		19.1.5 パイプへの書き込み
	19.2 FIFO(名前付きパイプ)
		19.2.1 FIFOの作成とオープン
	19.3 System VのIPC
		19.3.1 IPC資源の利用
		19.3.2 ipc()システムコール
		19.3.3 IPCセマフォ
		19.3.4 IPCメッセージ
		19.3.5 IPC共有メモリ
	19.4 POSIXメッセージキュー

20章 プログラムの実行
	20.1 実行ファイル
		20.1.1 プロセスの権限とケーパビリティ
		20.1.2 コマンドライン引数とシェル環境
		20.1.3 ライブラリ
		20.1.4 プログラムセグメントとプロセスメモリリージョン
		20.1.5 実行の追跡
	20.2 実行形式
	20.3 実行ドメイン
	20.4 Exec関数

付録A システムの起動
	A.1 先史時代:BIOS
	A.2 古代:ブートローダ
		A.2.1 ディスクからのブート
	A.3 中世:setup()関数
	A.4 ルネッサンス:startup_32()関数
	A.5 近世:start_kernel()関数

付録B モジュール
	B.1 モジュールにすべきか?
		B.1.1 モジュールのライセンス
	B.2 モジュールの実装
		B.2.1 モジュールの利用度数カウンタ
		B.2.2 シンボルの公開
		B.2.3 モジュールの依存関係
	B.3 モジュールの組み込みと削除
	B.4 必要になってからのモジュール組み込み
		B.4.1 modprobeプログラム
		B.4.2 request_module()関数

参考文献
	UNIXカーネルについての書籍
	Linuxカーネルについての書籍
	PCアーキテクチャに関する本とIntelマイクロプロセッサのテクニカルマニュアル
	その他のオンラインの情報源
	Linux開発に関する研究論文

ソースコード索引
索引

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

詳解 Linux カーネル第3版 第1刷正誤表

2007年3月28日更新

位置
p88
17行目
しかし、チェスプロセスが単なる1つのプロセスのときは、
しかし、チェスプログラムが単なる1つのプロセスのときは、
p217
下から4行目
その場合でもraw_read_trylock()関数は正しく動作します。raw_read_trylock()関数は、減算前のカウンタ値が0以下であれば、戻り値を1とします。
その場合でも_raw_read_trylock()関数は正しく動作します。_raw_read_trylock()関数は、減算前のカウンタ値が0より大きい値であれば、戻り値を1とします。
p223
15行目
call _ _up
call __up
p358
図8-6
num + osize
num × osize
p646
12行目
要求したページがすでにロックされていた場合、関数はエラー番号を返します。 p_optr
要求したページがすでにロックされていた場合、関数はNULLを返します。
p649
20行目
Tag[1]配列
tag[1]配列
p878
2行目
従来のメモリリージョ割り付けでは、
従来のメモリリージョン割り付けでは、

Feedback

皆さんのご意見をお聞かせください。ご購入いただいた書籍やオライリー・ジャパンへのご感想やご意見、ご提案などをお聞かせください。より良い書籍づくりやサービス改良のための参考にさせていただきます。
[feedbackページへ]