「Linux を(わりと)シンプルな構成でビルドして Qemu で起動する」では何をやっているのか。そして initramfs とは何か
「わりとシンプルな構成」とは
こちらの記事のことです→ Linux を(わりと)シンプルな構成でビルドして Qemu で起動する
ここではタイトルを省略して「わりとシンプルな構成」と記します。
「わりとシンプルな構成」 の ざっくりとした流れ を見ると以下のことを行っています (∩´∀`)∩
- qemu をインストールして
- カーネルを設定して、ビルドして
- initramfs を作って
- qemu で起動(∩´∀`)∩
Linux のブートシーケンス
流れは分かりましたが、「わりとシンプルな構成」に登場する initramfs とはなんでしょうか。
initramfs は Linux が起動する途中に利用するファイルシステムです。
全体を理解するために、まず Linux が起動する順番を把握します。一般のご家庭の PC (逸般の誤家庭ではありません) で Linux が起動する順番は以下の通りです。
- 電源 ON: PC の電源を ON します。
- UEFI or BIOS: マザーボード上の UEFI が起動されます。 UEFI はハードディスク上のブートローダーを読み込み、起動します。
- ブートローダー: Linux カーネルを読み込み、起動します。
- Linux カーネル: initramfs をマウントし、initramfs 上の init を実行します。
- initramfs 上の init: ルートファイルシステムをマウントし、systemd を実行します。
- systemd: udev によりハードウェアを扱えるようにしたり、デーモンを実行します。
参考 ブートプロセスの概要 | 管理ガイド | SUSE Linux Enterprise Server 12 SP3
Linux のカーネルと initramfs とルートファイルシステム
Linux のブートシーケンスのうちここでは以下のものに注目します。
- Linux
- カーネル
- initramfs
- ルートファイルシステム
カーネルとは
The Linux Kernel Archives でダウンロードできるやつです。ユーザーランド(ls や cat コマンドなど)は含まれません。
initramfs とは
cpio のアーカイブです。Linux が起動するときに一時的に使われます。
カーネルは起動するとファイルシステムをマウントする必要がありますが、起動時はまだどのデバイスがあるか分かっていません。デバイスが分からないのでディスクをマウントできません。
どのデバイスがあるかを知るためには udev が使われます。udev がデバイスを検知したあとデーモンやツールを使って Linux を起動させます。
デーモンやツールは /usr にあったりします。システム構成 (RAID だったり LVM だったり暗号化されていたり) によっては /usr が起動デバイスと異なるデバイスにあります。RAID なら mdadm 関連のツールが必要ですし、 LVM なら LVM 関連のツールが必要です。そういうときのために initramfs が活躍します。 initramfs に最低限のツールを入れておき、デバイスを検知し、ルートファイルシステムをマウントし、Linux を起動させます。
ルートファイルシステムとは
/ にマウントされたファイルシステムのことです。普段生活するときに使っているお馴染みの場所です。 「rootfs」 という単語もありますが、 「rootfs」と「ルートファイルシステム」は別のものです。
参考
- ramfs, rootfs and initramfs 何はともあれこの文書
- initramfsについて - Qiita initramfs 関連のコードリーディング
- rootfs (Linux) ‐ 通信用語の基礎知識
https://www.wdic.org/w/TECH/rootfs (Linux) - Initramfs/ガイド - Gentoo Wiki
- initramfsについて
「わりとシンプルな構成」の initramfs は何をやっているのか
再び initramfs の話題です。
上記の通り initramfs は cpio アーカイブ、または cpio アーカイブを gzip で圧縮したものです。
アーカイブとしては tar がよく使われますが (拡張子が .tar.gz や .tar.xz などが使われていればそうです) initramfs では tar ではなく cpio が使われています。cpio が使われる理由は cpio のほうがファイル構造が分かりやすいからだそうです ( ramfs, rootfs and initramfs )
「わりとシンプルな構成」では以下のように initramfs を作成しています initramfs の作成
$ echo init | cpio -o -H newc | gzip > initramfs.cpio.gz
つまり cpio アーカイブを gzip 圧縮しています。
cpio のオプションの意味は以下の通りです Ubuntu Manpage: cpio - copy files to and from archives
-
-o
: アーカイブを作成する -
-H newc
: SVR4 形式のフォーマット
initramfs は SVR4 形式である必要があるらしいです。
「わりとシンプルな構成」を真似して initramfs.cpio.gz を作成しました。
file コマンドで見てみるとただのデータと言われます。
$ file initramfs.cpio.gz
initramfs.cpio.gz: gzip compressed data, from Unix, original size modulo 2^32 872448
initramfs を覗くためのコマンドに lsinitramfs があるので使ってみます。init が入っています ( init で実行するプログラムの作成 で作った init です)
$ lsinitramfs initramfs.cpio.gz
init
そして、作成した initramfs を使って Linux カーネルを起動させます カーネルの起動
$ qemu-system-x86_64 -kernel ./bzImage -initrd ./initramfs.cpio.gz -append "console=ttyS0" -nographic
Discussion