Linuxカーネルについて 2014/01
Linuxカーネルの役割 ① ハードウェアに対する アプリケーション 操作をアプリケーション が意識しなくてよい システムコールインターフェース カーネル関数 ハードウェア
Linuxカーネルの役割 ② 以下の機能をアプリケーションに提供し、 ハードウェアに対する操作を統一的にする。 ・プロセス管理 ・メモリ管理 ・ファイルシステム ・ネットワーク ・プロセス間通信 etc...
Linuxカーネルのディレクトリ構成 ・kernel - Linxuカーネルの動きを制御する ・mm - 実メモリ管理、仮想記憶等のメモリ管理 ・fs - ファイルシステム関連 ・net - ネットワーク関連 ・init - カーネル起動時に呼び出される初期処理 ・crypto - 暗号処理共通関数 ・block – ブロック型デバイスのための共通処理 ・divers - デバイスドライバ ・sound - サウンドドライバ ・arch - CPUアーキテクチャに依存したコード群 ・include – 各種ヘッダーファイル Etc..
Linuxカーネルの動きを追う ソースが何百万行もあるので、 まずはブートプロセスから見てみる。
起動時の処理 ① CPUアーキテクチャ非依存の処理を見る Init/main.c のstart_kernel関数 asmlinkage void __init start_kernel(void) { char * command_line; extern const struct kernel_param __start___param[], __stop___param[]; smp_setup_processor_id(); lockdep_init(); debug_objects_early_init(); boot_init_stack_canary(); cgroup_init_early(); …
起動時の処理 ② 150行に渡ってひたすら初期化の関数を呼び出している。。。 全て追うと膨大な量になるので、更に読む箇所を絞り、割り込みハンドラを登録している箇所を 読んで見る。割り込みハンドラはtrap_init関数で登録されている。 ※割り込みハンドラとは 現在実行中の処理を一旦中断して、優先的に別の処理を行うこと。 例えばキーボードの入力を検知して、押されたキーに対応する処理を優先的に実行する等。
trap_init void __init trap_init(void) { int i; #ifdef CONFIG_EISA void __iomem *p = early_ioremap(0x0FFFD9, 4); if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) EISA_bus = 1; early_iounmap(p, 4); #endif set_intr_gate(0, ÷_error); // 除算エラー set_intr_gate_ist(2, &nmi, NMI_STACK); // NMI割り込み set_system_intr_gate(4, &overflow); // オーバーフロー set_intr_gate(5, &bounds); // BOUN範囲外 ...
割り込みテーブルの仕組み 各割り込み番号毎にセグメントとオフセットが 格納されており、それぞれCPUの CS(コードセグメント) IP (インストラクションポインタ) に格納されて実行される。 ※要するに各割り込みに対応する関数への アドレスが登録され、実行される。
割り込みの種類 ・外部装置割り込み SCSIホストアダプタ、ネットワークカード、端末装置などが生成する割り込み。 ・タイマー割り込み タイマーコントローラが一定周期で割り込みを発生させる。 Linuxでは2種類のタイマー割り込み(グローバルタイマー割り込み、ローカルタイマー割り込み) がある。 ・プロセッサ間割り込み マルチプロセッサ環境において、ほかのCPUへ何らかの事象を通知するために利用される。 割り込み要求を受けたCPUは、その事象に対応する処理を実行する ・NMI(マスク不可割り込み) 緊急時の障害対応目的で利用される
感想 Linuxカーネルはとんでもなく膨大な量なので、 読みたい箇所を絞って読まないと 大変なことになる。 今回は概要と、割り込みの部分しか 紹介できなかったので、 次回は別の部分を深く掘り下げたいと思う。
参考書籍 ・Linuxカーネル2.6解読室 ・Linuxカーネル解析入門 ・Linuxのブートプロセスをみる