起動用 RAM disk(initrd)の使い方 =============================== Written 1996 by Werner Almesberger and Hans Lermen 翻訳:こじまみつひろ initrd はブートローダーに RAM ディスクをロードする機能を付加します。こ の RAM ディスクはルートファイルシステムとしてマウントされ、そこから各 種のプログラムを起動することが可能です。その後、本当のルートファイルシ ステムを別のデバイスからマウントし、initrd が作ったルートファイルシス テムは /initd ディレクトリに移すかアンマウントします。 initrd はシステムを 2 段階で起動するために作成されました。まず最初の段 階で最低限のドライバのみを組みこんだカーネルを起動し、initrd から各種 のモジュールをロードするようにします。 操作方法 -------- initrd を使うと、システムは以下のように起動します。 1) まずブートローダーがカーネルと起動用 RAM ディスクをロードする 2) カーネルは起動用 RAM ディスク(initrd)を「普通の」 RAM ディスクに 変換し、initrd が使っていたメモリを解放する。 3) initrd はルートパーティションとして読み書き可能でマウントされる。 4) ルートパティションにある /linurc が実行される(このファイルは実行 可能であれば、シェルスクリプトも含めてどんなファイルでもいい。 /linuxrc は uid 0 で実行され、基本的に init ができる全てのことが 実行可能) 5) linuxrc が終了すれば、「本当の」ルートファイルシステムがマウントされる。 6) ルートファイルシステムに initrd というディレクトリがあれば、 initrd の内容はそのディレクトリに移される。ディレクトリが無ければ initrd はアンマウントされる。 7) 新たにマウントされた「本当の」ルートファイルシステムから、 (/sbin/init を起動する)通常の起動過程が実行される。 注意 1 : initrd を / から /initrd に移す際には unmount しませんので、 initrd 上にあるプロセスが動いているままでも移すことができます(あるいは ファイルシステムをマウントしたままにする、詳細は後述)。もし /initrd ディ レクトリが無ければ、initrd はその上のプログラムが使われなくなった時点 でアンマウントするしかありません。アンマウントできない場合、メモリにそ のまま残ります。 注意 2: initrd の下にマウントされたファイルシステムも引き続きアクセス 可能ですが、/proc/mounts のエントリは更新されません。また、/initrd が なく、initrd がアンマウントできない場合、その下のファイルシステムごと 「消滅」して、それらが再マウントされることを防ぎます。ですから、initrd から通常のファイルシステムに移行する際には、通常、ルートファイルシステ ムと /proc 以外のファイルシステムは全てアンマウントすることをお勧めし ます。 起動用 RAM ディスクが利用していたメモリを解放するためには /initrd をア ンマウント後、freeramdisk(「プログラムの入手先」の節を参照)コマンドを 実行します。 起動時のコマンドラインオプション ------------------------------- initrd 用に新しいオプションが用意されました。 initrd= (LOADLIN only) 指定したファイルを起動用の RAM ディスクに指定します。LILO の場合、 /etc/lilo.conf で INITRD 変数に RAM ディスクのイメージの在処を指定す る必要があります。 noinitrd initrd のデータは保存されますが、RAM ディスクには変換されずに「通常 の」ルートファイルシステムがマウントされます。initrd 上のデータは /dev/initrd を経由して読むことができます。この場合、initd 上のデータ はどんな構造をしていてもよく、ファイルシステムである必要もありません。 このオプションは主にデバッグ用に使います。 /dev/initrd は読み出し専用で、一度しか使えません。/dev/initrd を使っ ている最後のプロセスが終了すれば全てのデータは消去され、/dev/initrd は読み出せなくなります。 root=/dev/ram initrd をルートファイルシステムとしてマウントし、/linuxrc を起動しま す。もし /linuxrc が無ければ、RAM ディスクをルートファイルシステムと してマウントしまま通常の起動プロセスを実行します。このオプションは主 にフロッピーディスクから起動する際に用います。直接マウントされたファ イルシステムに比べて initrd を経由した方が多少速くなり、圧縮ファイル システムを使うことも可能です。さらに、LOADLIN と組み合わせることで RAM ディスクを直接 CD-ROM やハードディスクからロードすることも可能で、 E:\loadlin E:\bzImage root=/dev/ram initrd=E:\rdimage のように、CD からフロッピーを使わずにブートすることもできます。 インストール ------------ まず、「通常の」ルートファイルシステムを以下のような手順で用意します。 # mknod /dev/initrd b 0 250 # chmod 400 /dev/initrd # mkdir /initrd ルートファイルシステムが起動時に作成される場合(インストール用のフロッ ピーを作る場合など)は、ルートファイルシステムを作成する途中に、上記の 手順を実行する必要があります。 厳密に言えば、initrd の操作には /dev/initrd も /initrd も必須ではない ことに注意してください。でも、これらを使えば initrd の実験がずっと簡単 になります。また、/initrd を用意しておけば、「実際の」システムから initrd 用のデータを操作することも可能です。 次に、RAM ディスクと起動用 RAM ディスク機能を持ったカーネルが必要です。 また、initrd が実行するプログラムに必要な機能(ELF や a.out のバイナリ 機能やファイルシステム)もカーネルに組みこんでおく必要があります。 次に、RAM ディスクイメージを作成します。これはブロックデバイス上にファ イルシステムを作り、必要なファイルをそこにコピーして作ります。最新のカー ネルでは、少なくとも 3 つのデバイスが使用可能です。 - フロッピーディスク(どこでも使えるが非常に遅い) - RAM ディスク(速いが物理メモリを割りあてる必要がある) - ループバックデバイス(もっとも美しい解決策だが、改造した mount が必要) ここでは RAM ディスクを使う方法について説明します: 1) /dev/ram(ブロックデバイスで major 1, minor 1)があることを確認する。 2) 適当な大きさで、空のファイルシステムを作る # mke2fs -m0 /dev/ram 300 (スペースが重要になる場合は Ext2 ではなく Minix FS で作る方がいい) 3) 適当なディレクトリにファイルシステムをマウントする # mount -t ext2 /dev/ram /mnt 4) そのファイルシステム上にコンソール用のデバイスを作る # mkdir /mnt/dev # mknod /mnt/dev/tty1 c 4 1 5) initrd 環境を使うために必要なファイルを全てコピーする。最も重要なファ イルは /linuxrc で、/linuxrc には実行可能ビット("x")を立てることをお 忘れなく 6) RAM ディスクをアンマウントする # umount /dev/ram 7) 作成したイメージをファイルにコピーする。 # dd if=/dev/ram bs=1k count=300 of=/boot/initrd 8) RAM ディスクを解放する。 # freeramdisk /dev/ram initrd の実験には非常用フロッピー(Slackware の rescue.gz など)を使い、 /linuxrc を /bin/sh などへシンボリックリンクしておけばいいでしょう。例 えば、 # gunzip /dev/ram # mount -t minix /dev/ram /mnt # ln -s /bin/sh /mnt/linuxrc # umount /dev/ram # dd if=/dev/ram bs=1k count=1440 of=/boot/initrd # freeramdisk /dev/ram これでカーネルを再起動して initrd をロードします。現在のところ、 LOADLIN 1.6 と LILO 18 が initrd をサポートしています(入手先は後述)。 LOADLIN からは以下のように起動します。 LOADLIN initrd= 例えば、 LOADLIN C:\LINUX\VMLINUZ initrd=C:\LINUX\INITRD LILO の場合、/etc/lilo.conf の global セクションか respective kernel セクションに INITRD= の指定をします。例えば、 image = /vmlinuz initrd = /boot/initrd として、/sbin/lilo を実行します。 さぁ、initrd で遊んでみましょう。 ルートデバイスの設定 -------------------- ルートデバイスは、デフォルトではカーネルの一般的な設定になります。すな わち、コンパイル時の環境や rdev、コマンドラインでの root=xxx の指定、 LILO の /etc/lilo.conf での指定したデバイスがルートデバイスになります。 initrd を NFS マウントしたルートファイルシステムと組み合わせて使うこと も可能です。そのためには nfs_root_name と nfs_root_addrs という起動用 オプションを使います。 initd の環境の中からルートデバイスを変更することも可能ですが、そのため には /proc ファイルシステムがマウントされていなければいけません。/proc ファイルシステムをマウントすると、以下のファイルが操作可能になります。 /proc/sys/kernel/real-root-dev /proc/sys/kernel/nfs-root-name /proc/sys/kernel/nfs-root-addrs real-root-dev には新しいルートファイルシステムとなるデバイスの番号を書 きこむことで変更できます。例えば、/dev/hda1 を新しいルートファイルシス テムにする場合、 # echo 0x301 >/proc/sys/kernel/real-root-dev とします。NFS マウントされたルートファイルシステムの場合、 nfs-root-name と nfs-root-addrs を使い、real-root-dev には 0xff を指定 します。例えば、 # echo /var/nfsroot >/proc/sys/kernel/nfs-root-name # echo 193.8.232.2:193.8.232.7::255.255.255.0:idefix \ >/proc/sys/kernel/nfs-root-addrs # echo 255 >/proc/sys/kernel/real-root-dev ルートデバイスが RAM ディスクに指定された場合、ルートファイルシステム は /initrd へ移らず、ブートプロセスは起動用 RAM ディスク上の init を起 動します。 使い方の例 ---------- initrd の実装の主たる目的は、モジュール化されたカーネルの設定をシステ ムのインストール時に行うことです。このためには以下の手順に従います。 1) システムはフロッピーやその他のメディアから最小限の構成のカーネル (RAM ディスク、initrd, a.out ext2 FS 程度を組みこんだ)で起動し、 initrd をロードします。 2) /linuxrc の中で(1)「実際に」マウントするルートファイルシステム(デバ イスタイプやデバイスドライバ、ファイルシステムなど)と (2)配布メディ ア(CD-ROM, ネットワーク、テープ、、)を決めます。これはユーザーに尋 ねてもいいし、自動検出してもいいし、両者を合せた形でも構いません。 3) /linuxrc が必要なモジュールをロードします。 4) /linuxrc がルートファイルシステムを作成し、使用可能にします(この 時点ではそれほど十分なシステムでなくても構いません) 5) /linuxrc はルートファイルシステムとその他マウントされているファイ ルシステムをアンマウントし、/proc/sys/kernel/.. 等を設定して終了し ます。 6) ルートファイルシステムをマウントします。 7) この段階で、実際のファイルシステムにアクセス可能になり、システム にブートローダーをインストールできます。 8) ブートローダーを initrd とシステムを起動するのに必要なモジュール をロードするように設定します(/initrd は修正可能で、アンマウントし てから /dev/ram 経由でファイルへイメージを書き出します) 9)これでシステムが起動可能になったので、以下のインストール作業を行う ことができます。 ここに示した initrd の鍵となる役割は、肥大した「一般的な」カーネルやカー ネルの再コンパイル/再リンクなどをせずに、通常のシステム用の設定データ を再利用することです。 initrd が役立つ 2 つめの場面は、一人の管理者が設定の異なるさまざまなハー ドウェアにLinux をインストールする場合です。そのような場合、カーネルは できるだけ少ない種類にして(理想は一つ)、システムに依存した設定情報も可 能な限り小さくしておくことが必要になります。そのためには、必要なモジュー ルを全て組みこんだ共通の initrd を作り、/linuxrc か /linuxrc が読みこ むファイルのみを設定ごとに用意すればいいでしょう。 3 つ目の場面は、ずっと便利な「復旧用ディスク」を作る場合です。起動時に は、「ルート FS のあるパーティション」といった情報はわからないのですが、 initrd から読みこんだシステムはユーザーフレンドリーな対話形式で必要な 情報を設定し、整合性をチェックすることも可能です(簡単な自動検出も可能 です)。 さらに、CD-ROM の作成者も CD からずっと簡単にインストールさせることが 可能になります。LILO のブートフロッピーと CD から initrd 経由で大きな ramdisk を起動したり、LOADLIN を使って、フロッピー無しで CD から ramdisk を読みこむことが可能です。 initrd はかなり一般的なメカニズムなので、これ以外の使用方法も見つかる でしょう。 プログラムの入手先 ----------------- bzImage と initrd パッチ(bzImage は zImage の拡張版で、カーネルを直接 1 MB 以上の領域にロードし、最大 2 MB までのカーネルが使えるようになり ます)は ftp://lrcftp.epfl.ch/pub/people/almesber/lilo/bzImage+initrd-1.3.71.patch.gz か ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/bzImage+initrd-1.3.71.patch.gz にあります。 LOADLIN 1.6 は ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/loadlin-1.6-pre8-bin.tgz から入手できます。 LILO 18 は ftp://lrcftp.epfl.ch/pub/people/almesber/lilo/lilo.18dev3.tar.gz から入手できます。 initrd を作ってみる簡単な例と 'freeramdisk' プログラムは ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/initrd-example.tgz にあります。