linuxを起動する際,そのハードウェア用のデバイスドライバをカーネルに組み込んでおく必要があります。ただ常に使うハードウェアが決まっている場合(個人のPC等や組み込み機器)はこれで良いんですが,いろいろなPCに一つのカーネルで対応させようとすると,多くのデバイスドライバをカーネルに前もって組み込んでおかねばならない。この場合サイズがすごく大きくなっちゃう等の問題が出てくる。
ルートファイルシステムをマウントした後なら,そこにあるモジュール(/lib/modules/に入っているモジュール)をアクセスできるが,起動時はルートファイルシステムもマウントしていない状態なんでここをアクセスすることは出来ない。
でも,ルートファイルシステムをマウントするまでと言ってもルートファイルシステムをマウントするには,ハードディスクを認識しないとダメで,それにはATAドライバやらSCSIドライバやら,ファイルシステムとかいろいろなドライバがハードウェアに応じて必要になる。
そこでinitrd(Initial RAM Disk)というからくりが使われている。ハードディスクをルートファイルシステムとしてマウントする前に,一時的にマウントする「ミニルート(mini root)」みたいな物である。このミニルートには,ハードディスクをルートファイルシステムとしてマウントするのに必要となる可能性があるモジュール等一式を入れておいて,ハードウェアに応じて必要なモジュールをミニルートから読むようにする。その後,実際のハードディスクをマウントして,/ (ルート)をミニルートからハードディスクへ切り替えればOKになる。
ただ,initrdは作成が面倒くさい。initrdはRAMディスクというブロックデバイスなので,普通のファイルシステムでmkfsしなければならない。initrdにモジュールを追加しようとすれば,initrdイメージをループバックデバイス経由でマウントして,内容を変更するということをしなくちゃダメだし,もしファイルシステムが一杯にでもなったりしたら,initrdイメージをつくり直す必要もある。
という事で,initrdに代わる仕掛けとして,linux kernel 2.6からはinitramfsと呼ばれる仕掛けが導入された。これは,RAMディスクというブロックデバイスを用いるのではなく,RAM上に直接ファイルシステムを作るramfsを用いた「ミニルート」である。
initrd | initramfs | |
イメージ | ファイルシステム(ext3など+gzip) | アーカイブ(cpio+gzip) |
実装 | ブロックデバイス(RAMディスク) | ファイルシステム |
実行 | /linuxrc | /init |
rootfsマウント | 適当なディレクトリへマウントしてpivot_root | 適当なディレクトリへマウントして/へswitch_root |
init起動 | /linuxrc終了後,カーネルが起動 | /initがexec /sbin/initする |
initramfsだと,単に適当な場所にディレクトリを作成して,その中に必要なツール類を埋めてcpio で固めればよいので,作成しやすい。またcpioファイルが,kernelそのものと一体化されるのも特徴。
ブートパラメータとして「initrd=」を渡すと,ブートローダがイメージをメモリ上に読み込んでカーネルに渡す。するとカーネルはそのイメージがファイルシステムなのか,cpioアーカイブなのか調べる。もしファイルのmagic numberがcpioであれば,ramfsとしてマウントする。そして/initが実行可能ならば,initramfsとして扱い,/initを起動する。
新しくコメントをつける