Linux学習 システムアーキテクチャ 101-2 システムの起動

カーネルは起動されると、高度にハードウェアを認識・制御し、ルートファイルシステムのマウントなど様々な初期化処理を行います。
ブートローダはカーネルと初期RAMディスク（initramfs）の内容をメモリ上に展開し、カーネルはメモリ上に展開された初期RAMディスク内の、ファイルシステムへアクセスするために必要なドライバやスクリプトを使用してルートファイルシステムをマウントします。その後、initという特別な最初のプロセスをルートファイルシステムから起動します。
「SysVinit」と呼ばれる従来のinitプログラムを採用しているシステムでは、initプロセスとして「/sbin/init」が起動されます。なお、カーネルはブートローダの次に起動されます。

カーネルのログが記録されるなど、Linuxでメインで使用されるログファイルは「/var/log/messages」です。

システム起動時には様々なメッセージが出力されます。起動時に出力されたメッセージは後からdmesgコマンドで確認できます。
以下はdmesgコマンドの出力例です。

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654702369936_k33718.jpg)


dmesgコマンドはカーネルが出力するメッセージが格納されるリングバッファの内容を出力します。
リングバッファはマシンの再起動やシャットダウンによってリセットされますが、運用中に一杯になると古い情報から上書きされていきます。手動でリングバッファの内容をクリアするには、rootユーザで「dmesg --clear」を実行します。


UpstartはSysVinitを改善した新しい仕組みです。Red Hat Enterprise Linux(RHEL)やUbuntuに採用されていましたが、現在はsystemdへの置き換えが進められています。
Upstartではバックグラウンドで動作するデーモンプロセス（サービス）や、一度だけ実行させたい処理（タスク）を「ジョブ」と呼び、ジョブ単位で起動処理の管理を行います。
Upstartは各ジョブの実行に必要な前提条件を「イベント」で管理し、前提条件がすべて成立した時点でジョブを実行します。SysVinitのように順次起動していくのと異なり、サービスの起動に必要な条件が成立した時点で起動処理が行われるため不要な待機時間がなくなります。また、各ジョブの実行がパラレル（並列）に行われるため、関連のない独立したサービスは同時に起動させることができます。
イベントはシステム上の変化を検知するだけではなく、initctlコマンドで発行することもできます。

systemdの管理にはsystemctlコマンドを使用します。systemctlコマンドの書式は以下のとおりです。
systemctl サブコマンド [ Unit名 ]
主なサブコマンドの一覧

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654702552977_kkkkk34236.jpg)


Linuxが何らかの原因で正常に起動できない場合、CD-ROM/DVDやUSBなどのインストールブートメディアからレスキューモードでシステムを起動することができます。
レスキューモードで起動できた場合は、CPU/メモリといったハードディスク以外の装置には問題がないと考えられますので、レスキューモードで起動したシステムから起動に失敗するハードディスクのファイルシステムをマウントできるかを確認します。
レスキューモードでファイルシステムを正常にマウントできた場合は、「/var/log」配下のログでエラーを確認したり、重要なファイルを取り出せる可能性があります。

一般的なLinuxシステムでは、BIOS/UEFI、ブートローダ、カーネル、initの順にブートプロセスが進行します。　
BIOS/UEFI → ブートローダ → カーネル → init

「SysVinit」と呼ばれる従来のinitプログラムを採用しているシステムでは、カーネルから起動されるinitプロセスとして「/sbin/init」を起動します。initは起動されると、設定ファイル「/etc/inittab」の記述に基づいて、自動起動するべきプロセスを立ちあげるなど、アプリケーションレベルの初期化を行います。

systemdで扱う処理はUnitという単位で管理します。Unitには各機能ごとに拡張子が割り当てられており、拡張子を見ることでどういった機能のためのUnitかが判別できるようになっています。

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654705218339_kk34236.jpg)


各サービスの稼働状況や起動設定を管理するにはsystemctlコマンドを使用します。systemctlコマンドの書式は以下のとおりです。
systemctl サブコマンド [ Unit名 ]
※Unit名に拡張子がない場合、.serviceの拡張子を持つUnitが指定されたものとみなされます
主なサブコマンドの一覧

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654705504825_kkkkk34236.jpg)


UEFI（Unified Extensible Firmware Interface）は、IntelがBIOS（Basic I/O System）を置き換えるために考案したEFIの統一仕様です。GUIでの操作をサポートしていたり、ファームウェアが使用可能なメモリ量の上限が緩和されているなど、BIOSよりも高機能化しています。
ESP（EFIシステムパーティション）はUEFIシステムにおいて、物理的なマシンを起動し、ファームウエアが読み込まれた後、その後の起動シーケンスで最初にアクセスされる領域になります。ESPは「/boot/efi」にマウントされます。

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654827080711_kk34267.jpg)


また、GPT（GUID Partition Table）形式のHDDからの起動をサポートしています。GPTは、BIOSで起動ディスクとしてサポートしているMBR形式のパーティションテーブルの上限2.2TB（2TiB: テビバイト）という制約を大幅に超える、9.4ZB（8ZiB: ゼビバイト）までのHDDを管理することができるパーティションテーブルの形式です。3TBを超える大容量HDDを起動ディスクとして使用する場合はUEFIとGPTを使用する必要があります。ただし、Linuxの場合GRUB2 ブートローダがGPTをサポートしているため、BIOSからGRUBローダーをロードできればGPT形式のハードディスクからの起動は可能です。

systemdで扱う処理はUnitという単位で管理します。Unitには各機能ごとに拡張子が割り当てられており、拡張子を見ることでどういった機能のためのUnitかが判別できるようになっています。

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654827154063_kk34236.jpg)


systemdはSysVinitを置き換える新しいinitの仕組みです。
systemdで扱う処理はUnitという単位で管理します。Unitは設定ファイルであり、Unitの設定に従ってsystemd自体が処理を実行します。SysVinitのようにスクリプトを実行するわけではありません。
systemdはUpstartと同様、各サービスを並列起動することができます。そのため、順次起動していくSysVinitに比べて高速なシステム起動や停止が行えます。
また、SysVinitではプロセスをPIDによって管理していましたが、systemdではcgroupsというLinuxカーネルの機能によってプロセスのリソースを管理できます。

systemdはSysVinitを置き換える新しいinitの仕組みです。systemdでは以下のデーモンプロセスが連携して動作しています。

![](https://paper-attachments.dropbox.com/s_EAB9421F2980520784F38B8A425A4F19203DBA505ECEF799BDFAC8338713EFAD_1654827243383_k34236.jpg)


systemdの動作するシステムではsystemd-journaldデーモンを動作させ、ログの一元管理を行います。systemd-journaldはsystemdから起動したプロセスの標準出力やsyslogへのログメッセージをバイナリ形式で記録します。
systemd-journaldが書き込むログファイルはバイナリ形式のため、catコマンドなどで中を表示することが出来ません。systemd-journaldのログを表示するには journalctlコマンドを使用します。
journalctlコマンドの書式は以下のとおりです。
journalctl [オプション] [検索文字列]
バイナリ形式は、0 と 1 のビットの並び（ビット列）でデータが表現されていることをいいます。 

systemdの動作するシステムではsystemd-journaldデーモンを動作させ、ログの一元管理を行います。systemd-journaldはsystemdから起動したプロセスの標準出力やsyslogへのログメッセージをバイナリ形式で記録します。
systemd-journaldが書き込むログファイルはバイナリ形式のため、catコマンドなどで中を表示することが出来ません。systemd-journaldのログを表示するには journalctlコマンドを使用します。

journalctlコマンドの「-k」オプション、または「--dmesg」オプションで、dmesgコマンドと同じ情報（起動時にカーネルが出力したメッセージ）が出力されます。

ブートローダからカーネルに渡されたパラメータは「/proc/cmdline」ファイルで確認できます。

コンピュータの電源を入れると、まずBIOSが起動し、記憶装置（HDD）等に関して最低限の認識をして起動デバイスの優先順位を決定します。その後、優先順位に従って各デバイスの先頭セクタにあるMBR（ブート用の特殊領域。ブートローダが格納されている）を読み込み、得られたブートローダに制御を移します。ブートローダが得られない場合は次のデバイスのMBRを読み込みます。
起動デバイスの優先順位は、BIOSセットアップ画面で任意の順序に設定変更できます。BIOSセットアップ画面はコンピュータの起動時に特定のキー（DEL、F2など）を押すことで呼び出せます。
MBR 【Master Boot Record】 マスターブートレコード
MBRとは、ハードディスクなどのストレージ（外部記憶装置）の最も先頭にある、起動に必要なプログラムや情報を記録した小さな領域。 コンピュータの起動時に最初に読み込まれる。

ブートローダはカーネルと初期RAMディスク（initramfs）の内容をメモリ上に展開し、カーネルはメモリ上に展開された初期RAMディスク内の、ファイルシステムへアクセスするために必要なドライバやスクリプトを使用してルートファイルシステムをマウントします。その後、initという特別な最初のプロセスをルートファイルシステムから起動します。
カーネルイメージと、カーネルのバージョンに対応する初期RAMディスクは「/boot」ディレクトリに格納されます。初期RAMディスクは展開してイメージ内のディレクトリ・ファイルを参照することができます。

コンピュータの電源を入れると、まずBIOS(Basic Input Output System)が起動し、記憶装置（HDD）等に関して最低限の認識を行います。
BIOSが古い場合、大容量の記憶装置(HDD)を正常に認識できない(実際より少ない容量を認識するなど)場合があります。BIOSをアップデートすることで、この問題を解消できることがあります。