起動用 RAM disk(initrd)の使い方
===============================

Written 1996 by Werner Almesberger <almesber@lrc.epfl.ch> and
		Hans Lermen <lermen@elserv.ffm.fgan.de>

翻訳：こじまみつひろ<isle@st.rim.or.jp>

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=<path>    (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 <rescue.gz >/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 <kernel> initrd=<disk_image>

例えば、 LOADLIN C:\LINUX\VMLINUZ initrd=C:\LINUX\INITRD

LILO の場合、/etc/lilo.conf の global セクションか respective kernel 
セクションに INITRD=<path> の指定をします。例えば、

  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
にあります。

