- 本記事にはアフィリエイト広告が含まれます -
こんにちは、キクです。
本記事は、僕が自己学習で学んだことをブログでアウトプットするシリーズになります。
今回は『Linuxにおけるブートプロセス』について調べたことを書いていこうと思います。
本記事の内容
それでは、よろしくお願いします。
本題:ブートプロセスについて
今回はLinuxが起動するまでの流れ「ブートプロセス」について学習しました。
本質的には同じことが書いてあると思うのですが、調べれば調べるほどサイトによって若干書いてあることが違っていて混乱しました。
本記事には一旦腑に落ちた内容として整理したものを書いておきます。
関連調査
ここからはLinuxのブートプロセス関連で調べたキーワードや処理について記載していきます。
関連キーワード
BIOS(Basic Input Output System)
電源投入後、最初に起動するプログラム
マザーボードに内蔵チップとして組み込まれており、カーネル認識前でも動作可能
必要に応じて新しいバージョンに書き換えることができる
BIOSによってシステム起動に必要な「起動デバイス(HDD / CD-ROM / USBなど)」が認識され、必要な「ブートローダ(=起動プログラム)」が読み込まれる
BIOSのバージョンが古いと、最新のアダプタ類を正しく認識できず、本来利用可能なアダプタが正常に利用できない(構成エラーが発生する)ことがある
このような場合には、BIOSを最新のバージョンにアップデートするなどの対応が必要
BIOSには予め「ブートデバイス情報」が設定されており、起動時にはその情報を元に認識しにいく
BIOSでは、以下のような処理が実施される
- メモリのチェック
- ハードウェア設定の読み込み
- 起動デバイスのチェック
- 起動デバイスのMBR領域に格納されてブートストラップローダを実行
POST(Power On Self Test)
BIOSによるデバイスの初期化プロセスのこと
MBR(Master Boot Record)
HDDなどの「起動デバイス」の先頭セクタのこと
BIOSはMBRをメモリ上にロードし、MBR領域にあるプログラム( = ブートストラップローダ)に制御を移す
全体サイズは512バイトで、以下のような内訳となっている
ブートストラップローダ
起動デバイス(内蔵ハードディスクやCD/DVDメディアなど)のMBR領域に書き込まれた446バイトのプログラムコード
起動デバイスの別の場所にあるブートローダ(GRUBなど)をメモリに読み込む
ブートローダ
起動デバイスに保存されている「カーネル本体」と「初期RAMディスクファイル」をメモリに読み込む
このとき、ブートローダは設定ファイル「/boot/grub2/grub2.cfg」を読み込んで起動メニューを表示する
この表示メニューからメモリに読み込んで起動するカーネルと初期RAMディスクのペアを選択することができる
なお、各読み込み対象は基本的に以下のパスに格納されている
ブートローダが起動するとカウントダウンが開始され、その間にカーネルを選択することができる
何も選択しなかった場合にはデフォルトのカーネルが起動する
ブートセクタ / PBR(Partition Boot Record)
各基本パーティションの先頭セクタのことを指す
パーティションテーブル
MBR内の領域のひとつ
複数のパーティションに関する情報が保存されている
IPL(Initial Program Loader)
OSを起動させるためのブートローダの「残りの機能」を呼び出すための機能を持つ
この「残りの機能」は、ブートローダの2ndステージと呼ばれることもある
MBR/PBRは512バイトと非常に小さな領域で、ここに格納されているIPLはさらに小さなサイズである
この小さなプログラムに、OSを起動するためのブートローダの全内容を含めるのは困難である
そのため、IPLにはブートローダの「一部のプログラムコード」のみを持たせ、PBRの後続セクタに格納されている「残りの機能」を読み込むことで後続処理を続ける形となっている
IPLから呼び出されたブートローダの「残りの機能」によって後続のOSファイルを読み込み、最終的にOSが起動する流れとなる
初期RAMディスク
カーネルが起動した後は、まずは起動ディスクにアクセスして各種ファイルシステムをマウントする必要がある
このとき、起動ディスクにアクセスするためにデバイスドライバが必要となる
しかし、カーネル起動直後は必要なデバイスドライバを読み込んでいないため、上記ディレクトリにアクセスすることができない
この問題を解決するのが初期RAMディスクである
初期RAMディスクの実態は、デバイスドライバをはじめとする「カーネル起動直後に使用するファイル群」をまとめたアーカイブファイルである
また、初期RAMディスクはブートローダによって既にメモリ上に読み込まれているため、カーネルは初期RAMディスクを利用してデバイスドライバを読み込むことが可能となっている
初期RAMディスクの中身は以下のコマンドで確認することができる
# lsinitrd /boot/initramfs-カーネルバージョン.img
paxコマンドを利用することで初期RAMディスクをtmpディレクトリなどに解凍して、直接中身を確認することもできる
初期RAMディスクの中には、必ず「init」という名前の実行ファイルがある
このファイルを実行することで、ルートファイルシステムのマウントに必要なカーネルモジュールをロードしたりする
また、最終的に読み込む「ルートファイルシステム」上にも「init」プログラムが存在する
このinitプログラムはどのプロセスよりも先に実行されるため、常に「PID:1」となる
いわゆる初期化プロセスである
前者のinitプログラムが実行されることでルートファイルシステムがマウントされる
その後、ブートプロセスが進行していく中で後者のinitプログラムが実行される
参考:初期RAMディスクについて
参考:Linuxのブートプロセス
参考:【Linux】システムの起動まとめ
RAMディスク
メモリ上にファイルシステムを作成する機能
ループバックマウント
初期RAMディスクのような「ファイル」をファイルシステムとしてマウントする機能
カーネル
Linuxの根幹となるシステム
以下のような役割を担う
カーネルは以下のような要素から構成される
- 核となる部分
- コンパイル時に静的にリンクされるカーネルモジュール
- 起動後に必要に応じて動的にメモリに読み込まれるローダブルカーネルモジュール(/lib/modules/version/kernel)
カーネルはブートローダからメモリに読み込まれると、自身の初期化シーケンスを実施する
その後、メモリにロードされている初期RAMディスクをマウントする
初期RAMディスクのマウント後、それを利用してルートファイルシステムをマウントする
カーネルのバージョン情報は「/proc/version」に格納されており、以下のようなコマンドで確認できる
[確認例1]
# cat /proc/version
Linux version 5.15.59-v8.2.el9 (mockbuild@88c6f946b38a4410a07280c4fbe2912c) (gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2), GNU ld version 2.35.2-24.el9) #1 SMP PREEMPT Tue Aug 30 01:59:02 UTC 2022
[確認例2]
# uname -a
Linux localhost.localdomain 5.15.59-v8.2.el9 #1 SMP PREEMPT Tue Aug 30 01:59:02 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
カーネルの起動
以下のような処理が行われる
- ハードウェアの検出
- メモリの初期化
- システムクロックの設定
- IRQの設定
- ルートパーティションのマウント
- initプログラム(/sbin/init)の実行
処理内容はdmesgコマンドで確認可能
GRUBについて
ブートローダの一種で、ハードディスクなどからOSを起動するためのプログラム
多数のファイルシステムを認識可能
シェル機能も搭載している
■インストール方法
下記コマンドを実行すると、/dev/sdaのMBRにGRUB2がインストールされる
# grub2-install /dev/sda
■設定ファイル
以下2パターンある模様
- /boot/grub/grub.cfggrub-mkconfigコマンドにより自動生成されるもの手動での編集は避ける
- /etc/default/grub手動で設定したい場合にはこのファイルを編集する
編集の流れとしては、ファイル2を手動で編集した後、下記コマンドでファイル1の書き換えをするっぽい?
# grub2-mkconfig -o /boot/grub2/grub.cfg
参考:【Linux】ブートローダとは?とブートローダのインストール方法
関連処理
初期RAMディスク利用前の事前処理
以下のような処理が行われる
- メモリ上の初期RAMディスクファイルから一時的なファイルシステムを作成(機能名:RAMディスク)
- 上記ファイルシステムをマウント(処理名:ループバックマウント)
- 初期RAMディスクに含まれるファイル群を上記RAMディスク領域に展開して利用
初期RAMディスク上のinitプログラム実行について
「実際のルートファイルシステムのマウント準備」および「同ファイルシステムへのアクセスの準備」を行う
ルートファイルシステムが存在するデバイスにアクセスするためのドライバなどのモジュール郡を読み込んでくれる
必要なモジュールが読み込まれると、udevによってInitramfsに対して必要なデバイスが提供される
参考:Linuxのブートプロセス
参考:10 ブートプロセスの概要
ディスク装置にアクセスする仕組みの違い
■BIOS
ブートローダを読み込む際にブートデバイス(内蔵ディスクなど)にアクセスするが、この時にはデバイスドライバを必要としない
BIOSはマザーボードを製造するメーカーが作成するソフトウェアであるため、マザーボードに接続されたディスク装置にアクセスする機能が事前に用意されている
この機能を利用することで、デバイスドライバを必要とせずに自身の力でディスクにアクセスできる
ただし、機能としては限定的になる
■ブートローダ
カーネルや初期RAMディスクを読み込む際にディスク装置にアクセスするが、BIOS同様にデバイスドライバは不要
これはブートローダがBIOSの機能を呼び出してディスクにアクセスしているためである
■カーネル
先述の通り、BIOSの機能でのディスクへの接続は「機能が限定的」であったり、すべてのディスク装置に対してアクセスできるわけではない
そのような背景も踏まえて、カーネルではデバイスドライバを利用してディスクにアクセスする
参考情報
参考:【Linuxの基礎知識】起動の仕組みとカーネルについて!
参考:Linux道場入門編(LPI-JAPAN)
参考:ブートローダ
参考:【Linux】ブートローダーからカーネルまでの起動プロセス
参考:Initramfsのしくみ
参考:マスターブートレコード(MBR)_分かりそうで分からないシリーズ