初期RAMディスク(initial ramdisk)はLinuxカーネルのブート時に一時的なルートファイルシステムをメモリに読み込むための方式。 真のルートファイルシステムをマウントできるようになる前にファイルシステムを必要とする場面で使用される。 initrd とinitramfs(Linux 2.6.13 以降利用可能)の2種類の方式があるが、文脈によってはこれらを総称してinitrdと呼んでいる場合もある。 本記事でもinitrdとinitramfsの両方を記述する。

原理

Linuxディストリビューションの多くは、なるべく広範囲なハードウェアでブートできるよう、単一の汎用的カーネルイメージで出荷されている。この汎用カーネルイメージのデバイスドライバ群はローダブル・カーネル・モジュールになっており、メモリの限られたコンピュータやフロッピーディスクなどの低容量媒体からもブートができるようカーネルイメージを巨大化させない工夫をしている[1]。

このような方式では、ルートファイルシステムをブート時にマウントするには、事前に(ルートファイルシステム上にある)必要なモジュールを検出してロードしなければならないという問題が生じる(あるいは、ルートファイルシステムそのものがどこにあってどういう種類かを事前に知る必要がある)[1]。

さらに問題を複雑にするのは、ルートファイルシステムがソフトウェアRAIDボリュームだったり、LVMだったり、(ディスクレス・ワークステーションの場合)NFSだったり、暗号化されたパーティションだったりする点である。これらはマウントに当たって特別な処理を必要とする[2]。

もう1つ問題を複雑化させることとして、カーネルがハイバネーションをサポートしていることがある。ハイバネーションとは、システムを停止させて、その時点の全システムイメージをスワップパーティションや普通のファイルにダンプし、電源を切る機能である。次回立ち上げたとき、そのイメージをメモリにロードするには、ディスク上のイメージにアクセスできなければならない。

これらの特殊ケースに対応してカーネルにコードを加えるのを防ぐため、立ち上げの初期段階では一時的なルートファイルシステムを使う。これを初期ユーザ空間などと呼ぶ。このルートファイルシステムには真のルートファイルシステムのマウントに必要となる、ハードウェア検出、モジュールローディング、デバイス発見などのユーザー空間ヘルパーが存在する[2]。

実装

mkinitcpio, Arch Linux および関連ディストリビューションで initramfs を生成するソフトウェア
dracut

initrd のファイルシステムイメージ(およびカーネルイメージ)は、Linuxのブートローダやファームウェアがアクセスできる場所に格納しておく必要がある。これには、次のようなものがある。

ブートローダはカーネルとinitrdイメージをメモリ上にロードし、カーネルを起動する際に initrd のメモリアドレスを渡す。ブートの最終段階で、カーネルはinitrdイメージの先頭数ブロックを読み込み、そのフォーマットを判断する。

初期化用ルートファイルシステムが利用可能になると、カーネルは最初のプロセスとして /linuxrc を実行する。そのプロセスが終了 (exit) するとカーネルは真のルートファイルシステムのマウントが完了したと判断し、"/sbin/init" を実行して通常のユーザー空間の立ち上げ処理を開始する[3]。
initramfs 上で、カーネルは最初のプロセスとして /init を実行する。/init は終了 (exit) しない。

マウント準備

一部のLinuxディストリビューションでは、特定のコンピュータでのブートに必要なものだけ(ATA、SCSI、ファイルシステムのカーネルモジュールなど)を格納したカスタマイズしたinitrdイメージを生成する。その場合、ルートファイルシステムの場所や種類を実行時に判断するのではなく、initrdイメージ内に決めうちで書き込んでおくことが多い。

他のディストリビューション(FedoraやUbuntuなど)はより汎用的なinitrdイメージを生成する。その場合、ルートファイルシステムのデバイス名(またはUUID)のみを使い、他の必要な情報はブート時に発見しなければならない。したがって、ルートファイルシステムをマウントするまでに以下のようなタスクが実行される。

ルートファイルシステムを普通にルート(/)にマウントすると、初期化用ルートファイルシステム上のスクリプトなどを実行していたプロセスがうまくクリーンアップして終了できないため、次のような配慮が必要となる。

初期化用ルートファイルシステムには /linuxrc や /init といったシェルスクリプトがあるため、最小限のシェル(通常、/bin/ash)も含まれているし、他にも基本的なユーティリティ群(BusyBoxツールキットにあるようなもの)も格納されている。容量を節約するため、それらのシェルやユーティリティやライブラリ群は容量最適化オプション(gcc の "-Os" フラグなど)付きでコンパイルされ、klibcのような(このために開発された)標準Cライブラリの最小版とリンクされている[6]。

脚注・出典

  1. 1 2 Almesberger, Werner (2000), “Booting linux: the history and the future”, Proceedings of the Ottawa Linux Symposium
  2. 1 2 Landley, Rob (15 March 2005), Introducing initramfs, a new model for initial RAM disks, linuxdevices.com, オリジナルの2013-01-04時点におけるアーカイブ。
  3. 1 2 Almesberger, Werner; Lermen, Hans (2000), http://www.kernel.org/doc/Documentation/initrd.txt
  4. ↑ Landley, Rob (2005-10-17), ramfs, rootfs, and initramfs docs, take 2, Linux kernel source tree
  5. ↑ Fish, Richard (2005-07-06), pivot_root from initramfs causes circular reference in mount tree, Linux Kernel Bug Tracker 2009年2月28日閲覧。
  6. ↑ Garzik, Jeff (2002-11-02), initramfs merge, part 1 of N, Linux kernel mailing list

外部リンク

⌬ Phoenix Mesh CID: 未登録 IPFS未登録 📡 0ピア N=1 CRITICAL PQS C41
📋 変更履歴