カーネル

カーネルとは?

カーネルは、オペレーティングシステムの中核部分であり、ハードウェアとソフトウェアの間の仲介役を果たします。

以下にカーネルのイメージが格納されています。

ll /boot/vmlinuz-*64

カーネル本体

カーネル本体は、オペレーティングシステムの中核部分であり、ハードウェアリソースの管理、プロセス管理、メモリ管理、ファイルシステム管理、デバイス管理など、基本的なシステム機能を提供します。カーネル本体は、システムの起動時にメモリにロードされ、システムの動作を制御します。

主な役割

役割説明
プロセス管理カーネルは、プロセス(実行中のプログラム)の作成、スケジューリング、終了を管理します。複数のプロセスが同時に実行される場合、その実行順序を決定し、各プロセスに適切なCPU時間を割り当てます。
メモリ管理カーネルは、システムメモリの割り当てと解放を管理します。各プロセスが使用するメモリ領域を保護し、異なるプロセスが互いのメモリ領域を不正にアクセスしないようにします。
デバイス管理カーネルは、ハードウェアデバイス(ディスクドライブ、ネットワークインターフェイス、プリンターなど)との通信を管理します。デバイスドライバを通じてこれを行い、アプリケーションがハードウェアを効率的に利用できるようにします。
ファイルシステム管理カーネルは、ファイルシステムの作成、読み取り、書き込み、削除などの操作を管理します。異なるファイルシステムタイプ(ext4、xfs、btrfsなど)に対応し、データの整合性とセキュリティを維持します。
ネットワーク管理カーネルは、ネットワークプロトコルスタックを管理し、データの送受信を行います。これにより、システムがネットワークを介して他のデバイスと通信できます。

カーネルモジュール

カーネルモジュールは、カーネル本体の機能を拡張するためのコードです。これには、デバイスドライバ、ファイルシステム、ネットワークプロトコルなどが含まれます。カーネルモジュールはカーネルと一緒にビルドされ、カーネルの一部としてリンクされます。

主な特徴

特徴説明
静的リンクカーネルと一緒にビルドされ、カーネルの一部としてメモリに常駐します。
基本機能の提供重要な基本機能(例:デフォルトのファイルシステムサポートや基本的なデバイスドライバ)を提供します。
起動時にロードシステムの起動時に自動的にロードされます。

ローダブルカーネルモジュール(LKM)

ローダブルカーネルモジュール(Loadable Kernel Module, LKM)は、カーネルの動作中に動的に追加(ロード)または削除(アンロード)できるモジュールです。LKMを使用することで、システムを再起動せずにカーネルの機能を拡張できます。

特徴説明
動的リンクカーネルの実行中に追加や削除が可能。
柔軟な管理必要に応じてモジュールをロードし、使用しなくなったらアンロードできるため、システムの柔軟性が向上します。
専用コマンドmodprobe、insmod、rmmod、lsmodなどのコマンドを使用して管理。

イベント駆動型プログラム

カーネルはほとんど自発的に動作しません。基本的に待機し続け、ハードウェアやコマンド、アプリから指令があった場合に動作します。動作の引き金となるタイプのプログラムを「イベント駆動型プログラム」といいます。

カーネル処理のきっかけとなるイベントは主に以下の3つです。

  1. ハードウェア割り込み:周辺機器からCPUに送られる信号
  2. ソフトウェア割り込み:ソフトウェアの動作によってCPU内で発生
  3. システムコール:アプリケーションが発行。カーネル配下の機能を使ったりします。

割り込み

割り込みとは、現在処理している作業を一時中断し、別の処理を実施することです。

  1. CPUはメモリーの特定箇所にある「割り込みベクター」を参照し、そこに設定されているアドレスのにあるプログラムを実行します。実行される割り込み処理用のプログラムを「割り込みハンドラー」と呼びます。
  2. 割り込みハンドラ-の末尾には割り込み処理を終了させる命令があり、それを実行することで割り込み前の処理を再開できます。

システムコールの仕組み

システムコールを呼び出すとカーネルに処理を依頼するため、ソフトウェア割り込みが発生します。この割り込みによってカーネルが動作を始め、依頼された処理を実行します。

プロセス管理

プロセスとスレッド

Linuxでプログラムを実行すると「プロセス」または「スレッド」が作成されます。
プロセスは主にメモリーに読み込まれ、独立したメモリー空間を割り当てられて稼働中のプログラムのことです。
スレッドは他のプロセスやスレッドとメモリー空間を共有する特殊なプロセスのことです。
カーネルと同じメモリー空間で稼働するスレッドは「カーネルスレッド」と呼ばれます。

時分割処理

Linuxカーネルは、CPUやCPUコアの数が1つであっても、複数のプロセスやスレッドを同時に稼働できます。これはCPUで実行するプロセスやスレッドをカーネルが短い時間で切り替えることで実現しています。CPUやCPUコア数が1つの場合ある瞬間に稼働するプロセスは1つなのですが、切り替え時間が短いために、あたかも複数のプロセスが同時に稼働しているように感じられる。複数のCPUやCPUコアを装備するPCや、同時マルチスレッディング対応CPUを装備するPCでは同時に稼働できるプロセスの数が増えます。この場合も時分割処理をすることで、CPU数やCPUコア数以上のプロセスを(見かけ上)同時に稼働できます。

プロセススケジューラー

 実行待ちのプロセス群から、どのプロセスをどのぐらいの期間、どのCPUで実行するかを管理するのがカーネル内の「プロセススケジューラー」の役割です。プロセススケジューラーに求められるのは各プロセスを「公平に」かつ「効率よく」実行することです。
 すべてのプロセスを一定時間ずつ順に実行すれば公平性を実現できるように思えます。しかしプロセスの中には常時CPUで演算するものもあれば、ユーザーの入力待ちやデバイスの入出力処理待ちのためにCPUをあまり使わないものもあります。この両者を同じ期間実行した場合、前者はフルにCPUを使えますが、後者はすぐに待機状態に移行してしまってごく短期間しかCPUを使えなくなります。結果として後者のようなプロセスの応答性が悪化するなどの問題が生じます。
 またLinuxでは、各プロセスに異なる実行優先度を設定できるので、それを考慮したスケジューリングが必要です。

プロセス管理コマンド

メモリー管理

仮想アドレス空間

Linuxは複数のプロセスを稼働できます。また、複数のユーザーがシステムを共有する「マルチユーザー利用」にも対応しています。そのため各プロセスが利用するメモリー領域が重ならないようにする仕組みが必要です。これを解決するため各プロセスを独立したアドレス体系委を持つ「仮想アドレス空間」(仮想メモリー空間)内で稼働させます。仮想アドレス空間は仮想的に作り出したメモリー領域で実態は持ちません。実際に利用する場合は、実メモリーのアドレス空間にマッピングする必要があります。

ページング

Linuxでは「ページング」と呼ばれる方式で、仮想アドレス空間と物理アドレス空間をマッピングします。ページングはメモリー領域を小さな固定長の「ページ」の集合と捉え、ページ単位にメモリーを管理する方式です。

MMU(メモリー管理ユニット)

最近のCPUはMMU(メモリー管理ユニット)はページング対応機能を備えています。こうしたCPUでは、仮想アドレスと物理アドレスを対応付けるためのアドレス変換用テーブル(ページテーブル)を設定することで、自動的なアドレス変換を実現できます。ページテーブルは主メモリー上に配置し、CPU内の特殊な制御レジスターに(現在利用中の仮想アドレスに対応する)ページテーブルの位置を示す物理アドレスを格納しておく仕組みが一般的です。

デマンドページング

 プロセス生成時に作られる仮想アドレス空間のサイズは32ビットのx86系のCPUでは4Gバイトです。しかしこの仮想アドレス空間にある仮想ページすべてに物理ページが割り当てられるわけではありません。
 無駄を避けるため物理ページは、仮想ページに対して実際に入出力処理をしようとした際に初めて割り当てられます。このような割り当て方式を「デマンドページング」と呼びます。デマンドページング方式であれば実際に使った分だけのメモリーしか消費されません。
 デマンドページングは「例外」を利用して実装されています。プロセスが物理ページ未割り当ての仮想ページにアクセスすると「ページフォルト」というアクセス失敗を示すメモリー管理例外が発生します。この例外をトリガーにして物理ページの割り当て処理を実施し、失敗した仮想ページのアクセス処理を再開させることでデマンドページングが実現できます。

ページ回収

 空き物理メモリーが少なくなってくると、Linux カーネルは、使用中のページを調査して新規利用可能なページを確保する処理を実施します。これを「ページ回収」処理と呼びます。
 ページ回収処理は最近アクセスされていないページを対象にします。コンピュータのメモリーには「時間的局所性」という性質があり、直近にアクセスされたページは近い未来に再度アクセスされる可能性が高く、その逆に、最近アクセスされていないページは近い未来に再度アクゼスされる可能性が低いからです。ページが最近アクセスされたかどうかを調べやすくするため、Linuxカーネルは「LRUリスト」(Least RecentlyUsedリスト)を使って使用中の物理ページを管理しています。


 ページ回収処理では、主に二つの処理を実施します。一つは、ページキャッシュに利用している物理ページの内容を破棄して空き物理ページにする処理です。ページキャッシュはファイルのデータをコピーしたものです。必要になったら再度フアイルからデータを読み出せばよいわけですから、内容が変更されていなければ破棄して構いません。内容が変更されているページキャッシュ(これをダーティなページキャッシュなどと呼びます)は、一度データをファイルに書き戻す必要があります。カーネルはダーティなページキャッシュを書き戻す処理を定期的に実施しています。

メモリースワッピング

 ページ回収のもう一つの処理は、プロセスが作業領域などのために確保した無名ページのデータを、ハードディスクなどの「スワップ領域」に書き出して空き物理ページを確保する処理です。この処理を「ページアウト」(あるいはスワップアウト)と呼びます。
 物理ページがページアウトされている仮想ページにアクセスがあった場合は、新たな物理ページが割り当てられ、そこにページアウトされたデータが書き戻されて使用されます。この処理を「ページイン」(あるいはスワップイン)と呼び、ページアウト/ページイン処理機構を総称して「メモリースワッピング機構」と呼びます。
 メモリースワッピングにより、システム全体で物理メモリーの容量以上のメモリーを使用できるようになります。しかしページアウト/ページイン処理には、通常のメモリーアクセスに比べて格段に時間がかかりますから、こうした処理が発生し始めるとシステムの処理性能は大幅に低下します。

ページアウト


ページイン

OOM Killer

メモリー使用量が増えすぎ、ページ回収処理によっても必要な空き物理ページが確保できない状態になると、カーネルそのものの動作に支障が出る恐れがあります。こうした場合、最悪の事態を避けるためにLinux カーネルは「OOM Killer」(Out of Memory Killer)と呼ばれる処理を開始します。
 OOM Killerは、稼働中のプロセスのうちいくつかを強制的に停止させて、空き物理ページを確保する処理です。
 OOM Killerにより停止されやすいのは、使用中の物理ページやページアウトしているページが多いプロセスです。ただし、管理者権限を持つプロセスは、停止されにくくなっています。

デバイス管理

デバイスファイル

Linuxは、ほぼすべてのデバイスを「ファイル」として抽象化します。アプリケーションからデバイスにデータを入出力する場合は、この抽象化されたファイルに対してデータを入出力します。デバイス操作用のファイルは「デバイスファイル」と呼ばれ、一般に/devディレクトリー以下に配置します。

udev

 カーネルがデバイスの抜き差しのイベント情報を「udevd」というサーバーに通知します。udevdは、通知されたイベントに対応する処理ルールを、/etc/udev/rules.dディレクトリーや/lib/udev/rules.dディレクトリーから探し出し、それに従ってデバイスファイルの作成や削除、デバイスドライバの読み込みなどの作業を実施します。さらに「D-Bus」という仕組みを通じて、ディスクデバイスの自動マウント/アンマウントなどの、より進んだ自動処理を実現できます。

コメント

タイトルとURLをコピーしました