ブートプロセスについて知る

linuxのブートプロセス

ブートプロセスについて調べたことをメモ。

1.BIOS(UEFI)

コンピュータの電源がオンになるとハードウェアの自己診断(テスト)がスタートします。その後ハードディスクを認識した後、BIOSはハードディスク先頭の512B(MBR-マスターブートレコード)をメモリ(0x07C00)にロード、対象のアドレスにジャンプします。

2.ブートローダー

有名なものだとGrubなどはこのレイヤーに位置します。

先の0x07C00にロードされた512BのプログラムだけではもちろんあのGrubのような多くの機能を実現することはできません。そこでまずはは簡単な初期化処理の後、メインのプログラムをロードする処理を行って対象のアドレスにジャンプします。(この時点でファイルシステムは認識できる)

ここまで来ると(例えばgrubの場合は)configファイルを解釈し、ブートするosの選択をユーザーに促します。

ユーザーがosの選択を行うとgrubはvmlinuz(カーネルの一部)とinitramfs(ブートに用いる一時的なファイルシステム)をメモリ上にロードし、展開されたカーネルの先頭アドレスにジャンプします。

3.カーネルとinitramfs

vmlinuzは一部の初期化処理の後、カーネル本体の解凍を行いメモリにロード、対象のアドレスにジャンプします。その後残った必要な初期化処理を行うと、initramfsinitrd)を一時的なファイルシステムとしてマウントします。

initramfsにはinitが存在します。カーネルはinitramfsのマウント後、このinitramfsinitを実行します。ここでは主にメインのファイルシステムを読み込むのに必要な処理を行い、実際にマウントを行います。

ここでカーネルが直接メインのファイルシステムを読み込まないのは、ファイルシステムが暗号化されていたりと複雑なことが多いためです。ファイルシステムは複数のハードで構成することができますが、仮に通常のinit(例えばsystemd)が簡単に読み込めるハードに保存されていたとしても、これらが必要とするファイル群が正しくファイルシステムにマウントされているとは限らないのです。

ファイルシステムの読み込みが完了すればカーネルは通常のinitを実行することが可能になります。

4.プロセス(PID1)の起動

ここまでファイルシステムが完全に使用できるようになりました。ここでやっと通常のinitが起動できます。実態としては/sbin/initですが、ubuntu20.04の場合は/lib/systemd/systemdへのシンボリックとなっています。

ロギング

3.カーネルとinitramfsの起動後は通常のlinuxログが吐かれます。以下はその例です。

参照方法内容
dmesgor/var/log/dmesgカーネルリングバッファーログ。カーネルによって出力されるログが記録されます。printk()された出力に対応します。
/var/log/kern.logdmesgをファイルとして保存したものです。dmesgはリングバッファーなのである程度昔のログは残らないのに対し、kern.logは比較的長時間残ります。
/var/log/syslogsyslogによって回収されたログです。カーネルに関係しないログも含まれています。ちなみにkern.logを管理しているのもsyslogです。

参考程度にとどめますがsystemdを採用しているディストリビューションの場合、カーネルやその他のアプリのログを大元で管理しているのはjournaldです。journaldはシステムのあらゆるログを収集し、syslogに関係あるログをsyslogに送ります。

さいごに

ディストリビューションごとの差はあるけどSUSEとかRHELなんかのドキュメントは結構分かりやすい。しっかりまとまってる。

参考

Built with Hugo
Theme Stack designed by Jimmy