Linuxカーネルの起動とプロセスについて

# Linuxカーネルの起動とプロセスについて

## PCの電源を入れた後、Linuxのブートプロセスは以下のステップで進行します：

### 1. **BIOS/UEFI**
   - PCの電源が入ると、BIOSまたはUEFIがハードウェアの初期化を開始します。
   - 次にブートデバイスを確認し、ブートローダーへ制御を渡します。

### 2. **ブートローダー (例: GRUB2)**
   - ブートローダーは、カーネルイメージと初期RAMディスクをメモリに読み込みます。

### 3. **カーネルの起動**
   - カーネルは、ハードウェアの構成や接続されているデバイスを認識し、初期化します。

### 4. **イニシャライザ (例: systemd or init)**
   - イニシャライザがシステムの初期化プロセスを管理します。これには、ネットワークの設定やデーモンの起動などが含まれます。

### 5. **ログインプロンプトまたはグラフィカルログイン**
   - ユーザーはログインプロンプトで認証情報を入力するか、グラフィカルなログイン画面を通じてシステムにログインします。

### 6. **デスクトップ環境**
   - ユーザーがログインすると、デスクトップ環境が起動します。ここからユーザーはアプリケーションを操作することができます。

### 7. **アプリケーションの起動**
   - ユーザーはデスクトップ環境からアプリケーションを選択し、起動します。これにはウェブブラウザ、テキストエディタ、ゲームなどが含まれます。

このシナリオを通じて、電源を入れてからユーザーがアプリケーションを操作するまでの流れが明らかになります。各ステップはシステムの安定性とセキュリティを確保するために重要です。

## カーネルによるプロセス管理

Linuxカーネルは、システムのリソース（CPU、メモリ、I/Oデバイスなど）を効率的に管理し、多数のプロセスが同時に実行されるようにする役割を持っています。この記事では、カーネルによるプロセスの管理方法、特にコンテキストのライフサイクル、ページテーブル、メモリ管理、コンテキストスイッチに焦点を当てて説明します。

### コンテキスト
現在の実行状態（CPUレジスタの値、プログラムカウンタ、スタックポインタなど）は、システムのメモリに保存されます。

### ページテーブルとメモリ管理

ページテーブルは、仮想メモリアドレスを物理メモリアドレスにマッピングする役割を果たします。これにより、各プロセスは独立したアドレス空間で実行されているかのように感じますが、実際には物理メモリは効率的に共有されています。

### コンテキストスイッチ

コンテキストスイッチは、オペレーティングシステムのスケジューラが一つのプロセスから別のプロセスにCPUの制御を移すプロセスです。

1. **現在のプロセスのコンテキストの保存**:
   - CPUのレジスタ、プログラムカウンタ、フラグ、メモリマップなどの現在の状態が保存されます。

2. **新しいプロセスのコンテキストの読み込み**:
   - 次に実行されるプロセスのコンテキストがCPUに読み込まれ、そのプロセスが実行を再開または開始します。

3. **ページテーブルの切り替え**:
   - 新しいプロセスのページテーブルがアクティブになり、CPUが新しいプロセスの仮想メモリ空間にアクセスできるようになります。

このようなプロセスの管理とコンテキストスイッチングにより、マルチタスキング環境が実現され、複数のプロセスが同時に実行されているように感じるとともに、システムリソースが効率的に利用されます。カーネルは、これらのタスクを効果的に管理し、システムのパフォーマンスと安定性を確保する重要な役割を果たします。

## イニシャライザ（初期化システム）の詳細
Linuxにおけるイニシャライザ（初期化システム）は、システムがブートした後、さまざまな初期化タスクを実行する役割を果たします。`systemd` と `init` （System V init）は、Linuxで広く使用されている2つの初期化システムです。それぞれのステップについて詳しく説明します：

### `systemd`

1. **システムの起動**:
    - カーネルが起動し、`init`として知られるプロセスID 1のプロセスを開始します。Linuxシステムで`systemd`が使用されている場合、`/sbin/init` は `systemd` のシンボリックリンクです。

2. **ターゲットの選択**:
    - `systemd` は、特定の「ターゲット」に基づいてさまざまなサービスやデーモンを起動します。ターゲットは、System V initのランレベルのコンセプトに似ています。

3. **サービスの起動**:
    - `systemd` は、ターゲットにリストされているサービスやデーモンをパラレルで起動します。

4. **マウント**:
    - 必要なファイルシステムのマウントや、その他の初期化タスクを実行します。

### System V `init`

1. **システムの起動**:
    - カーネルが起動し、`init`プロセスが開始されます。

2. **ランレベルの設定**:
    - `/etc/inittab` ファイルを読み取り、デフォルトのランレベルを設定します。

3. **スクリプトの実行**:
    - 選択されたランレベルに対応するスクリプトが `/etc/rc.d/` 以下で実行されます。これには、サービスの起動やその他の初期化タスクが含まれます。

どちらのシステムも、ユーザーがログインしてシステムを使用する準備ができるまで、システムの起動プロセスを管理します。それぞれがいくつかの違いを持ちますが、目的はシステムを安全かつ効率的に起動することです。

`systemd` の「ターゲット」は、特定のシステム状態または構成に関連する一連のサービスやデーモンをまとめるための単位です。ターゲットは、System V `init` のランレベルの概念に相当しますが、より柔軟で機能的です。

System V init のランレベルは、0から6までの数字で表され、システムの特定の状態を示します。例えば、ランレベル3はマルチユーザテキストモード、ランレベル5はグラフィカルモードを意味します。

`systemd` のターゲットは、以下のように機能します：

### 1. **ターゲットの定義**:
   - ターゲットは一連のサービスや他のターゲットをグループ化します。
   - ターゲットは具体的な名前を持っており、その名前はそのターゲットがどのような目的で使用されるのかを示しています（例：`graphical.target`, `multi-user.target`）。

### 2. **依存関係**:
   - ターゲットは他のターゲットまたはサービスに依存することができ、依存関係が満たされた後に起動します。

### 3. **フレキシビリティ**:
   - `systemd` ターゲットはカスタマイズが可能で、新しいターゲットの作成や既存のターゲットの修正ができます。

### 4. **ステートの変更**:
   - システム管理者は、システムを異なるターゲットに移行することができ、それによりシステムの動作が変わります。

たとえば、`multi-user.target` はテキストベースのマルチユーザモードを意味し、`graphical.target` はグラフィカルなログインマネージャを起動するためのターゲットです。これにより、システムの起動プロセスがどのように進行するかを簡単に制御し、カスタマイズすることができます。

そして一度にアクティブにできるターゲットやランレベルは通常1つです。例えば、システムが起動時に特定のターゲット（またはランレベル）に移行し、そのターゲットで定義されたサービスやデーモンが起動します。

しかし、`systemd` のターゲットは他のターゲットに依存することができ、一つのターゲットが他の複数のターゲットを含む「集合」のように機能することができます。これにより、`systemd` は非常に柔軟で再利用可能な構成が可能です。

シングルユーザーモードやマルチユーザーモードなどのモードは、それぞれ特定のターゲットやランレベルに対応します。システムはそれらのモードに基づいて、適切なサービスとデーモンを起動または停止し、そのモードで定義された操作状態に移行します。

## `init`と`systemd`の比較

### init (System V init)

`init`はUNIXシステムの伝統的な初期化システムで、System V（SysV） initとしても知られています。以下のステップに従って動作します。

1. **ブート時のスクリプト実行**:
   - システムが起動すると、`/etc/inittab` ファイルに記述された指示に従って、一連のスクリプトが順番に実行されます。

2. **ランレベルの設定**:
   - `init`は異なるランレベルに基づいて動作し、それぞれのランレベルに応じて異なるスクリプトが `/etc/rc*.d` ディレクトリに置かれます。

3. **シーケンシャル処理**:
   - スクリプトはランレベルごとに順番に実行され、それぞれのスクリプトは一つのサービスまたはタスクを起動します。

`init`はそのシンプルさから、長い間標準的な初期化システムとして使われてきましたが、現代の多様な要求に対応するには限界があると考えられています。

### systemd

`systemd`は`init`の後継として開発された、より現代的な初期化システムです。`systemd`は次の特徴を持っています。

1. **並列処理**:
   - `systemd`はサービスの依存関係を管理し、可能な限り並列にサービスを起動します。

2. **ターゲットに基づく処理**:
   - `systemd`はランレベルの代わりにターゲットを使用し、より柔軟なシステム状態の管理を可能にします。

3. **イベント駆動型**:
   - サービスは、デバイスの接続やネットワークの利用可能性など、特定のイベントに基づいて起動されることができます。

4. **ログ管理**:
   - `systemd`は`systemd-journald`サービスを使用して、システムのログを集中管理します。

`systemd`はより複雑な現代のシステムに適した特徴を持ち、設定や管理が`init`よりも柔軟であるとされています。しかし、その複雑さから一部のユーザーからは批判もあります。それにもかかわらず、多くの主要なLinuxディストリビューションは`systemd`を標準の初期化システムとして採用しています。