Initramfs/ガイド
Linux ベースのコンピューターシステムでは、正しくブートするために initramfs が必要になることがあります。このガイドでは initramfs を適切に作成、管理する方法や initramfs のコンセプトを説明します。
initramfs のコンセプト
はじめに
一風変わったドライバーや構成を使っている、または暗号化ファイルシステムを使っているシステムでは、Linux カーネルが init バイナリに制御を渡すことができるようにするために、initramfs が必要です。
Linux のブートプロセス
Linux カーネルが(ブートローダーによって読み込まれた後に)システムの制御を得ると、自身のメモリー構造とドライバーを準備します。それから、制御をあるアプリケーション(通常は init)に渡します。そのアプリケーションの役割は、さらにシステムの準備をすることと、ブートプロセスが終わった時点ですべての必要なサービスが実行されユーザーがログインできる状態にすることです。init アプリケーションはサービスの中でも、検出されたデバイスをもとにシステムのさらなる読み込みや準備を行う udev デーモンを起動することによってその作業を行います。udev が起動されるとまだマウントされていない残りのファイルシステムがすべてマウントされ、それから残りのサービスが開始されます。
必要なファイルやツールがすべて同じファイルシステムにあるシステムでは、init アプリケーションは以降のブートプロセスを完全に制御できます。しかし複数のファイルシステムが定義されている(またはもっと風変わりなインストールがなされている)場合には、事はもう少しトリッキーになります:
- /usr パーティションが別のファイルシステムにある場合、/usr の中に保存されているツールやドライバーは /usr が利用可能になるまで使えません。そうしたツールが /usr を利用可能にするために必要な場合、システムをブートすることができなくなります。
- ルートファイルシステムが暗号化されている場合、Linux カーネルは init アプリケーションを見つけることができないため、ブートできないシステムになってしまいます。
この問題への古くからある解決策が initrd (initial root device) を使うことです。
initial root disk
initrd は、ルートファイルシステムの init アプリケーションに制御を渡す前に必要なファイルシステムをマウントするのに必要なツールやスクリプトを含む、メモリー内ディスク構造 (ramdisk) です。Linux カーネルはこのルートディスクにあるセットアップスクリプト(通常は linuxrc と呼ばれますが、その名前である必要はありません)を起動します。セットアップスクリプトはシステムの準備や真のルートファイルシステムへの切り替えを行い、そして init を実行します。
initrd を使う方法は必要なことをすべて行えますが、いくつか欠点もあります:
- これはれっきとしたブロックデバイスであり、ファイルシステム全体でオーバーヘッドが必要です; 固定サイズになります。initrd があまり小さすぎると必要なスクリプトがすべて収まりません。大きくしすぎるとメモリを浪費してしまいます。
- これは真の、静的なデバイスなので Linux カーネル内のキャッシュメモリーを消費しますし、(ページングのような)メモリーやファイルを管理するメソッドを使用しがちになります。これにより、initrd はますます多くのメモリーを消費することになります。
こうした問題点を解決するために initramfs が作られました。
initial ram file system
initramfs は tmpfs (サイズを柔軟に設定できる軽量なメモリ内ファイルシステム) をもとにした初期 RAM ファイルシステムで、特別のブロックデバイスを使用しません (したがってキャッシュは起こらず、前に述べたオーバーヘッドはすべて無くなります)。initrd と同様に、initramfs には真のルートファイルシステム上にある init バイナリが呼び出される前にファイルシステムをマウントするために必要なツールやスクリプトが含まれています。これらのツールは (暗号化ファイルシステム用の) 復号化抽象レイヤー、論理ボリュームマネージャー、ソフトウェア RAID、Bluetooth ドライバーベースのファイルシステムローダー等の場合があります。
initramfs の内容は cpio アーカイブを作ることで作成します。cpio は古い (しかし実績のある) ファイルアーカイバーです (そして、アーカイブファイルは cpio ファイルと呼ばれます)。cpio は tar アーカイバーと完全に同等です。ここで cpio が選ばれた理由は、コードの観点から実装がしやすく、また当時は tar がサポートしていなかったデバイスファイルをサポートしていたためです。
すべてのファイル、ツール、ライブラリ、(あれば) 構成設定などは cpio アーカイブに収められます。このアーカイブはその後 gzip ユーティリティーを使って圧縮され、Linux カーネルとともに保管されます。ブートローダーは、カーネルが initramfs が必要であると知ることができるように、ブートする際に Linux カーネルに initramfs を提示します。
initramfs が検出されると、Linux カーネルは tmpfs ファイルシステムを作成してアーカイブの内容をそこに展開し、それから tmpfs ファイルシステムのルートにある init スクリプトを起動します。このスクリプトは(たとえば追加モジュールの読み込み、暗号化抽象レイヤーの準備などを行ってマウントができるようにしてから)真のルートファイルシステムとその他の重要なファイルシステム(たとえば /usr や /var など)をマウントします。
ルートファイルシステムやその他の重要なファイルシステムがマウントされると、initramfs の init スクリプトはルートを真のルートファイルシステムに切り替え、ブートプロセスを続けるためにシステムの /sbin/init バイナリを起動します。
initramfs の作成
導入とブートローダーの設定
initramfs を作成するには、どのような追加ドライバー、スクリプト、ツールがシステムをブートするために必要なのか知っておくことが重要です。
ルートディスクとルートファイルシステムにアクセスできる必要があります
実際のところ、これは通常は CONFIG_SATA_AHCI または CONFIG_BLK_DEV_NVME (ディスクに関して)、およびCONFIG_EXT4_FS (ファイルシステムに関して) がカーネルに組み込まれている [=y] べきという意味です; もしそうでなく、これらがモジュールとして存在する [=m] 場合は、ブートを続行できるように、これらのモジュールをまず initramfs がロードする必要があるでしょう。
LVM を使用している場合には initramfs 内に LVM ツールが必要です。
ソフトウェア RAID を使用している場合には mdadm ユーティリティー、または DMRAID が必要、等々。ZFS と BTRFS についてもここで考慮する必要があるでしょう。
ユーザーのシステム用の initramfs (圧縮された cpio アーカイブ) 作成を支援する自動ツールがいくつかあります。もっともよく使われているのが dracut と genkernel です。同様に、完全なコントロールを望むユーザーは個人用のカスタム initramfs を簡単に手動作成することもできます。
作成が済んだら、initramfs を使用することを知らせるためにブートローダーの設定を調整する必要があります。
通常これは設定ファイルの再生成 grub-mkconfig -o /boot/grub/grub.cfg によって行われます。
たとえば initramfs ファイルが /boot/initramfs-5.15.32-gentoo-r1.img に保管されている場合、実行後の /boot/grub/grub.cfg の GRUB 設定は以下のようになるでしょう:
title Gentoo Linux 5.15.32-r1
set root='hd1,gpt2'
linux /boot/vmlinuz-5.15.32-gentoo-r1-x86_64
initrd /boot/initramfs-5.15.32-gentoo-r1-x86_64.img
genkernel を用いる
Gentoo のカーネルビルドユーティリティ Genkernel を initramfs の生成に使用することができます。genkernel は、カーネルと initramfs がどちらも自身によってビルドさることを期待していますが、場合によっては、genkernel によってビルドされた initramfs と、他の方法でビルドされたカーネルの組み合わせでも、動作するかもしれません (推奨はされません)。
genkernel を initramfs の生成に使う場合、/ ルートや /usr のファイルシステムをマウントするために必要な全てのドライバーやコードはカーネルに (モジュールとしてではなく) 組み込みとして含めることをおすすめします。これらが組み込まれていれば、genkernel を --no-ramdisk-modules
オプション付きで実行できます。
initramfs 内でモジュールが必要な場合は、次のように genkernel を実行してください:
root #
genkernel --install initramfs
システムによっては、以下のオプションのうちいくつかが必要になるかもしれません:
オプション | 説明 |
---|---|
--disklabel
|
/etc/fstab での LABEL= 設定のサポートを追加する
|
--dmraid
|
フェイクハードウェア RAID のサポートを追加する。 |
--firmware
|
システム上で見つかったファームウェアコードを追加する。 |
--gpg
|
GnuPG のサポートを追加する。 |
--iscsi
|
iSCSI のサポートを追加する。 |
--luks
|
LUKS 暗号化コンテナのサポートを追加する。 |
--lvm
|
LVM のサポートを追加する。 |
--mdadm
|
ソフトウェア RAID のサポートを追加する。 |
--multipath
|
SAN へのマルチ I/O アクセスのサポートを追加する。 |
--zfs
|
ZFS のサポートを追加する。 |
完了すると、できた initramfs ファイルが /boot に保存されます。
dracut を用いる
Dracut ユーティリティーは initramfs ファイルを管理することを唯一の目標として作られました。
Dracut ユーティリティーをインストールするには以下を実行してください:
root #
emerge --ask sys-kernel/dracut
次のステップは /etc/dracut.conf を編集して dracut を設定することです。
設定が終わったら、以下のように dracut を実行して initramfs を作成します:
root #
dracut
こうして生成されるイメージは /etc/dracut.conf の設定をもとに一般的なシステムブートをサポートします。また、個別のシステムに特化した initramfs を生成することもできます (この場合、dracut は既存のシステムから必要なツール、ドライバーなどの検出を試みます)。モジュールやドライバーを (分離されたモジュールやファームウェアへの参照としてではなく) カーネルに組み込んでいる場合には、--no-kernel
オプションを追加できます:
root #
dracut --host-only --no-kernel
詳細については dracut や dracut.cmdline のマニュアルページを参照してください:
user $
man dracut
user $
man dracut.cmdline
関連項目
- Initramfs — is used to prepare Linux systems during boot before the init process starts.
- Initramfs - make your own — build an initramfs which does not contain kernel modules.
- Custom Initramfs — the successor of initrd. It provides early userspace which can do things the kernel can't easily do by itself during the boot process.
- Early Userspace Mounting — how to build a custom minimal initramfs that checks the /usr filesystem and pre-mounts /usr.
外部の情報
- Linux カーネルドキュメント内の ramfs-rootfs-initramfs.txt ファイル。