  Ext-Rootfs-mini-HOWTO
  こじまみつひろ (isle@st.rim.or.jp)
  v0.4, 1997/05/14

  この文書では、NotePC を主な対象に、initrd を使って外付けの SCSI ディス
  んクや NFS マウントしたディレクトリにルートファイルシステムを取って
  Linux を起動する方法と 1 枚の FD に最小の Linux システムを組みこむ方法
  を解説します。

  1.  はじめに

  Note PC では HDD の容量の問題で、内蔵 HDD に Windows95 を残したまま、
  外付けの SCSI ディスクに Linux をインストールしたい、という状況がよく
  生じます。しかし、Linux で外付けの SCSI ディスクを使うためには pcmcia-
  cs が必要で、そのためには Linux を起動しなければならない、という「鶏と
  卵」的な問題がありました。

  しかし、Linux 2.0 のシリーズに採用された initrd という機能を利用すれ
  ば、 initrd で起動して pcmcia-cs を使えるようにし、外付け SCSI HDD を
  ルートファイルシステムにして起動する、ということができるようになりまし
  た。同様に、LAN カードを使って NFS ディレクトリにルートファイルシステ
  ムを置くことも可能です。

  この文書では、initrd を使って外付け SCSI HDD や NFS マウントしたディレ
  クトリにルートファイルシステムを置き Linux を起動する方法について説明
  します。

  2.  initrd とは？

  Linux 2.0 ではメモリ上にファイルシステムを作る ramdisk やファイルを
  ファイルシステムとしてマウントする loopback ファイルシステムがサポート
  され、ファイルシステムをきわめて柔軟に使うことができるようになっていま
  す。 initrd はこの 2 つのメカニズムを組みあわせたようなもので、起動時
  にファイルとして用意したファイルシステムを ramdisk 上に展開、そこを暫
  定的なルートファイルシステムとしてカーネルを立ちあげ、必要な処理をして
  から実際のルートファイルシステムを再マウントする、という 2 段ロケット
  的なブートを可能にします。

  この機能を使って、initrd 上に pcmcia-cs を置いておけば、initrd で起動
  した状態で PC カードを使用できるようになります。そして、ルートファイル
  システムを外付けの HDD や NFS サーバに置くと、内蔵 HDD には Linux パー
  ティションを置く必要はなくなり、Win95 のディスクの片隅に loadlin.ext
  とカーネルイメージ、圧縮した initrd ファイルを置いておくだけで Linux
  が使えるようになります。(FD に入れれば内蔵 HDD には一切ファイルを置く
  必要がなくなります)

  容量の問題で内蔵 HDD には Linux をインストールできない人や、Note PC で
  も複数のディストリビューション(Slackware, Red Hat, Debian)を切り替えて
  使ってみたい人には便利な機能でしょう。試していませんが MO や PD といっ
  たメディアをルートパーティションにして起動することも(動きはすごく遅く
  なるでしょうが)できるはずです。

  ただし、外付け SCSI HDD や NFS ディレクトリをルートパーティションにし
  た場合、当然のことですが使用中に PC カードを抜くことはできませんので、
  note PC の命である可搬性は大きく損なわれます。

  3.  外付け HDD をルートファイルシステムにする

  外付け HDD にルートファイルシステムを置く方法から説明します。

  まず、Win95 の載った Note PC と pcmcia-cs でサポートされている SCSI カ
  ード、外付けの HDD ドライブ、それらを接続するための SCSI ケーブル、タ
  ーミネータ等を用意します。Linux のインストールには CD-ROM を使うため、
  CD-ROM ドライブもあった方がいいでしょう。手元では以下のような構成で試
  しています。

  o  Note PC         : Toshiba 610CT

  o  CD-ROM ドライブ : Panasonic KXL-D740 4X CD-ROM

  o  SCSI カード     : 上記に付属のカード(Qlogic OEM)

  o  LAN カード      : Accton EN2212

  o  外付け SCSI HDD : iomega jaz 1GB

  インストールに使う Linux のディストリビューションはトッパンの「Linux
  入門」の CD-ROM(Slackware 3.1)を使うことにします。

  initrd はディストリビューションに依存する機能ではないので、Red Hat や
  Debian を使っても同様のことは実現可能だと思いますが、筆者は Slackware
  3.1 でしか試していません。

  1. まず、Windows 95 を起動して CD-ROM ドライブをシステムに認識させま
     す。この部分は Linux とは関係ないので、Windows 95 のマニュアルや
     CD-ROM ドライブのマニュアルを読んでください。

  2. 「Linux 入門」の CD-ROM に入っている pxmciax.gz の mount は以下の作
     業に必要な loopback デバイスのマウントをサポートしていないので、
     http://www.st.rim.or.jp/~isle/pcmciax2.gz
     <http://www.st.rim.or.jp/~isle/Linux/pcmciax2.gz> をダウンロードし
     ます。

  3. 「Linux 入門」の 1 枚目の CD-ROM から、
     (D:\)install\notepc\tools\loadlin\loadlin.exe
     と(D:\)kernels\aha1542.s\zImage を Windows95 の領域にコピーしま
     す。Linux 用のディレクトリを作ってそこに入れておくのがいいでしょ
     う。以下ではこれらのファイルは C:\linux に置いてあるものとします。
     上でダウンロードした pcmciax2.gz も同じディレクトリに移しておきま
     す。

  4. Win95 をいったん再起動して、"Starting Windows95" のメッセージが出た
     時に F8 キーを押し、立ち上げモードの選択画面を出します。6 の
     "Command Prompt Only" を選び、コマンドプロンプト画面で起動します。

     Linux をブートする際、日本語モードでは画面が表示されなくなるので、
     "us" コマンドを実行して、忘れずに英語モードに切り替えておきましょ
     う。

  5. cd linux し、loadlin を使って Linux を起動します。この時、
     pcmciax.gz を initrd に指定し、ルートファイルシステムは initrd を展
     開して作成される ramdisk(/dev/ram0) を指定します。

     ___________________________________________________________________
         c:\linux > loadlin zimage initrd=pcmciax2.gz root=/dev/ram0
     ___________________________________________________________________

  6. pcmciax2.gz には pcmcia-2.8.22 相当の機能が組みこまれているので、サ
     ポートされている SCSI カードはそのまま認識できるはずです。接続して
     いる CD-ROM や外付け HDD がきちんと認識されているか確認してくださ
     い。

       pcmciax2.gz にはネットワークカードを使って NFS 経由でインス
       トールしたり、 EasyHard、PLIP、 SLIP 経由でもインストールで
  きるようにモジュールを用意していますので、ヒマと根性のある人
  は試してみてください(苦笑)。

  7. Slackware のインストール作業そのものは「Linux 入門」に詳しく説明し
     てあるので省略します。外付けの HDD を対象に、CD-ROM からインストー
     ルするように指定すれば、その後の設定は「Linux 入門」の記述に沿って
     進むはずです。ただし、今回は lilo を使わず loadlin.exe で起動します
     ので、最後の lilo のインストールの部分は飛ばして、内蔵 HDD に lilo
     をインストールしないようにしておきます。

  8. Slackware のインストールが終了したら、再起動する前に pcmciax2.gz に
     少し細工をして、initrd をマウントした時点で一度プロンプトを出すよう
     にしておきます。

     pcmciax2.gz を修正するには、このファイルを loopback ファイルシステ
     ムを使ってマウントしなければなりません。initrd には圧縮ファイルを自
     動的に展開する機能がありますが、loopback ファイルシステムには自動展
     開機能がないので、一度 pcmciax2.gz を展開する必要があります。

     pcmciax2.gz を展開するために、まず /dos のようなディレクトリを作
     り、そこに Windows95 のディスク領域をマウントし、gunzip で
     pcmciax2.gz を展開します。

     ___________________________________________________________________
         # mkdir /dos
         # mount -t msdos /dev/hda1 /dos
         # gunzip < /dos/linux/pcmciax2.gz > /dos/linux/pcmciax2
     ___________________________________________________________________

  pcmciax2 に細工するために、pcmciax2 をマウントするためのディレクトリ
  (/workdir)を作り、mount に -o loop オプションを指定して pcmciax2 ファ
  イルをファイルシステムとしてマウントします。

  ______________________________________________________________________
      # mkdir /workdir
      # /mnt/bin/mount /dos/linux/pcmciax2 /workdir -o loop
      # ls /workdir
      bin/     cdrom@   etc/     lib/     proc/    sbin/    usr/
      boot/    dev/     floppy/  mnt/     root/    tmp/     var/
  ______________________________________________________________________

  initrd では、initrd 上に linuxrc というファイルがあればそれをまず起動
  することになっています。ですから linuxrc を bin/sh にシンボリックリッ
  クしておけば、initrd を起動した状態で sh を使って対話的に各種の設定を
  行うことが可能になります。

  ______________________________________________________________________
      # ln -s bin/sh linuxrc
      # ls -l /workdir/linuxrc
      lrwxrwxrwx 1 root root 6 Jan 4 14:39 /workdir/linuxrc -> bin/sh*
  ______________________________________________________________________

  もう一つ、実際のルートファイルシステムになるパーティションに /initrd
  というディレクトリを作っておきます。initrd 経由で起動した時、実際のル
  ートファイルシステムになるパーティションに /initrd というディレクトリ
  があると、initrd で使った暫定版のルートファイルシステムはこのディレク
  トリに移して保存されます。

  ______________________________________________________________________
      # mkdir /workdir/initrd
  ______________________________________________________________________

  これでインストール作業が終了しました。システムを再起動して、再度 Win95
  をコマンドプロンプトモードで起動します。

  9. 今回はルートファイルシステムを対話的に設定したいので loadlin.exe を
     以下のように root= オプションは指定せずに起動します。initrd の指定
     も修正した pcmciax2 にしていることに御注意ください。

     ___________________________________________________________________
         c:\linux\> loadlin zimage initrd=pcmciax2
     ___________________________________________________________________

  10.
     この状態で起動すると、カーネルを展開した後、initrd 上にある linuxrc
     を実行し、プロンプトが出て止まります(linuxrc は sh へのシンボリック
     リンクなので、実際には sh が動いています)。この状態ではまだ pcmcia-
     cs が動いていないので、まず /etc/rc を実行して pcmcia-cs を使えるよ
     うにします。

     ___________________________________________________________________
      # /etc/rc
     ___________________________________________________________________

  /etc/rc が /rc/rc.d/rc.pcmcia を実行すると、 pcmcia-cs が機能するよう
  になり、SCSI カードやそれに接続された外部デバイスも認識されるようにな
  ります。正しく認識しているか、表示されるメッセージを確認してください。

  11.
     次にルートファイルシステムを外付けの SCSI ディスクに変更します。
     initrd を使っている場合、proc ファイルシステムの
     /proc/sys/kernel/real-root-dev というファイルにルートファイルシステ
     ムのデバイス番号を書きこんでやると、initrd を終了した際、そのデバイ
     スをルートファイルシステムとしてマウントします。

     ルートファイルシステムのデバイス番号は /dev/xxx ファイルを ls -l す
     れば表示されます。例えば、外付けの 1 つめの SCSI HDD のパーティショ
     ン 1 をルートファイルシステムにしたい場合、

     ___________________________________________________________________
         # ls -l /dev/sda1
         brw-r-----   1 root    disk   8,   1 Apr 29  1995 /dev/sda1
     ___________________________________________________________________

  なので、/dev/sda1 のデバイス番号は major が 8、minor が 1 です。この場
  合、"0x801" を /proc/sys/kernel/real-root-dev に書きこみます。

  ______________________________________________________________________
      # echo "0x801" > /proc/sys/kernel/real-root-dev
  ______________________________________________________________________

  同様に外付けの 2 つめの SCSI HDD 全体をルートファイルシステムにする場
  合、

  ______________________________________________________________________
      # ls -l /dev/sdb1
      brw-r-----   1 root    disk   8,   17 Apr 29  1995 /dev/sda1
  ______________________________________________________________________

  なので、"0x811" を /proc/sys/kernel/real-root-dev に書きこみます。2 台
  目の IDE ドライブの 2 つ目のパーティションならば、

  ______________________________________________________________________
      # ls -l /dev/hdb2
      brw-r-----   1 root    disk   3,  66 Apr 28  1995 /dev/hdb2
  ______________________________________________________________________

  なので "0x342" を書きこみます。

  ls -l /dev/xxx で表示されるデバイス番号は 10 進表記ですが、echo
  "0xaaa" で書きこむ場合は 16 進表記になっていることに御注意ください。

  12.
     実際のルートファイルシステムの設定が終われば exit を入力する
     か、ctrl-D を押して linuxrc(実体は sh)を終了します。すると、
     /proc/sys/kernel-real-root-dev に設定したルートファイルシステムを新
     しいルートファイルシステムにしてシステムが起動するはずです。

  13.
     Slackwareに標準の起動用スクリプト /etc/rc.d/rc.S は通常の desktop
     環境を前提にしているので nfsroot で使用するといろいろと問題が生じま
     す。具体的にどうすればいいかは現在も試行錯誤中ですが、nfsroot を
     fsck するのはヘンなので、fsck してる回りは全部コメントアウトして、
     必要なコマンドを動かしているところだけにしていいように思います。

  14.
     新しいルートファイルシステムで起動すると、古いルートファイルシステ
     ムは /initrd 以下に移され read only でマウントされています。initrd
     段階で動いていた各種のプロセスからはこのディレクトリはルートファイ
     ルシステムのままに見えるので、例えば cardmgr の見る /var/run/stab
     は /initrd/var/run/stab になります。

     pcmcia-cs では /var/run/stab に現在挿入されているカードの状態を書き
     こんで監視していますが、/var/run/stab が /initrd以下の read only
     ファイルシステム (/initrd/var/run/stab)に移動すると、カードを挿し替
     えた時の情報の更新が不可能になります。そのため、一旦 cardmgr を終了
     させてから再起動し、cardmgr が現在の /var/run/stab を参照するように
     します。

     ___________________________________________________________________
         # killall cardmgr
         # /sbin/cardmgr
     ___________________________________________________________________

  このためには、initrd に組みこんだ pcmcia-cs とルートファイルシステムに
  ある pcmcia-cs のバージョンや設定が同じになっている必要があります。

  pcmcia-cs が initrd 段階で組みこんだ pcmcia_core.o や i82365.o、ds.o
  の 3 つのモジュールは外付け SCSI HDD をルートファイルシステムにしてい
  る限り使用中なので取り除くことはできません。そのため再起動の際には
  "device busy" 等のエラーメッセージがいくつか出ますが、特に気にする必要
  はありません(と思う、、)。

  15.
     再起動した cardmgr は通常の /var/run/stab を見ながらカードの監視を
     行うため、新しいカードを挿入しても認識できるはずです。PC カードが正
     しく認識されるか、カードを抜き挿しして試してみてください。ただし、
     外付けの SCSI をルートファイルシステムにしている場合、SCSI カードを
     抜くと確実にハングアップしますので御注意ください。

  4.  NFS マウントしたディレクトリにルートファイルシステムを置く

  initrd を使えば pcmcia-cs 経由で LAN カードを使い、NFS マウントした
  ディレクトリにルートファイルシステムを置いた diskless Linux を構成する
  ことも可能です。

  NFS マウントしたディレクトリにルートファイルシステムを置く(NFS root)場
  合、カーネルの構築時に、NFS オプションと NFS root オプションを共に指定
  する必要があります。Slackware に付属のカーネルには NFS root オプション
  は指定されていないので、NFS root を使う場合にはカーネルを再構築する必
  要があります。カーネルを再構築する際に指定すべきオプションは ``「専用
  のシステムを作る」''節で解説します。

  NFS root を利用する場合、NFS サーバとなるマシンに必要なルートファイル
  システムを用意する必要があります。そのための方法については
  /usr/src/linux/Documentation/nfsroot.txt や nfs-root-mini-HOWTO を参照
  してください。

  また、NFS サーバとなるマシンでルートファイルシステムを export する際に
  はオプションとして /etc/exports ファイルで no_root_squash をオプション
  を指定し、ルート権限で NFS ディレクトリにアクセスできるようにしておき
  ます。

  ______________________________________________________________________
  /var/nfsroot    cyclone.rider.co.jp(rw,no_root_squash)
  ______________________________________________________________________

  NFS サーバとなるマシンのルートファイルシステムのあるディレクトリ(上記
  の例では /var/nfsroot)にある /etc/fstab も NFS マウント用に修正してお
  く必要があります。

  ______________________________________________________________________
  172.16.1.1:/var/nfsroot  /    nfs   rw,rsize=8192,wsize=8192,intr
  ______________________________________________________________________

  カーネルを NFS root オプションを指定して再構築し、initrd で起動する
  と、 /proc/sys/kernel/nfs-root-name と /proc/sys/kernel/nfs-root-addrs
  というファイルに書きこめるようになります。前者(nfs-root-name)にはサー
  バマシンでの NFS root のディレクトリを、後者(nfs-root-addrs)にはサーバ
  ーマシン、クライアントマシンそれぞれの IP アドレスを指定します。
  /proc/sys/kernel/real-root-dev には 0xff(255) を指定しておきます。
  例えば、サーバマシン(hurricane.rider.co.jp)の IP アドレスが
  172.16.1.1、クライアントマシン(cyclone.rider.co.jp)の IP アドレスが
  172.16.1.2、ネットマスクが 255.255.255.0 の場合、initrd で起動して、
  ネットワークカードが使えることを確認してから、

  ______________________________________________________________________
  # echo "/var/nfsroot" > /proc/sys/kernel/nfs-root-name
  # echo "172.16.1.2:172.16.1.1::255.255.255.0:cyclone  \
           > /proc/sys/kernel/nfs-root-addrs
  # echo 255 > /proc/sys/kernel/real-root-dev
  ______________________________________________________________________

  と書きこみ、linuxrc を終了すれば、hurricane 上の /var/nfsroot を NFS
  root にしてシステムが起動します。

  /proc/sys/kernel/nfs-root-addrsに書きこむ書式は nfsroot.txt にあるよう
  に、 <client-ip>:<server-ip>:<gw-
  ip>:<netmask>:<hostname>:<device>:<autoconf> という形で、省略した部分
  にはデフォルト値が使われます。

       Slackware 標準の /etc/rc.S ではルートファイルシステムをいっ
       たん read-only でマウントして fsck しますが、NFS root の場
       合、ルートファイルシステムはあらかじめマウントされているの
       で、その旨を示すエラーメッセージが表示されますが、多分大丈夫
       です(あまり使ってないので自信ありません。識者の御意見を教え
       てください。)

  メモリの少ないマシンで swap 領域も NFS 上に取る必要がある場合、 NFS
  swap patch
  <http://sunsite.unc.edu/pub/Linux/Incoming/etherboot-3.0b1.tar.gz> を
  あてて、カーネルを再構築してくださ。

  5.  専用のシステムを作るには

  pcmciax.gz は Slackware 3.1 のカーネルと組みあわせて使うように pcmcia-
  cs も 2.0.0 のカーネル用にコンパイルしていますので、カーネルをバージョ
  アップする際には pcmcia-cs も再コンパイルが必要です。

  initrd 経由で起動している場合、pcmcia-cs が initrd で起動するファイル
  システムの中に置かなければならないので、システムをバージョンアップする
  際には多少の注意が必要になります。

  5.1.  カーネルの再構築

  カーネルの再構築時には 以下の項目に注意して設定してください。これら以
  外のオプションはお使いの環境に合わせて設定します。

  o  "Loadable modules support" の "Enable loadable module support" と
     "Kernel daemon support" を設定。

  o  "General Setup" の "Kernel Support for a.out binaries" と "Kernel
     Support for ELF binaries" を設定(モジュールではダメ)。

  o  "Floppy, IDE, and other block devices" の "Loopback device support"
     、"RAM disk support" と "Initial RAM disk(initrd) support" を設定。
  o  "SCSI support" の "SCSI support"、"SCSI disk support" を設定。"SCSI
     tape support", "SCSI CD-ROM support", "SCSI generic support" は設定
     してもモジュールでも可。必須ではありませんが "Probe all LUNs on
     each SCSI device" も念のため設定しておきます。

  o  NFS root を使う場合は "File systems" 中の "NFS"と"NFS root"オプショ
     ンも設定します。

  カーネルをコンパイルする際には make zlilo ではなく、make zImage で
  /usr/src/linux/arch/i386/boot/zImage を作ります。この zImage を DOS 領
  域にコピーして、このカーネルイメージを loadlin.exe でロードするように
  します。

  ______________________________________________________________________
  # cp /usr/src/linux/arch/i386/booz/zImage /dos/linux/zimage.new
  ______________________________________________________________________

  カーネルのコンパイルが終れば、モジュール類も忘れずコンパイル、インスト
  ールしておきます(make modules; make modules_install)。

  次回に起動するときは loadlin.exe で zimage.new を指定します。

  5.2.  pcmcia-cs の再構築

  pcmcia-cs はルートファイルシステムと initrd の双方にインストールしてや
  る必要があります。pcmciax2 をループバックでマウントして
  /sbin/{cardmgr, cardctl} や /lib/modules/2.0.x/pcmcia 以下を入れ替える
  のも一つの方法ですが、この場合、pcmciax には libc-4.7.6 しか入っていな
  いことに注意してください。すなわち、コマンドである
  /sbin/{cardmgr,cardctl} をコンパイルする場合は a.out 形式でコンパイル
  する必要があります。

  このためには、pcmcia-cs を通常の make でコンパイルしてから、cardmgr
  ディレクトリに移り、Makefile に CC = /usr/i486-linuxaout/bin/gcc を追
  加して make clean; make します。いくつかのコマンドは a.out 形式でうま
  くコンパイルできないかも知れません。

  もう一つの方法は、 ELF 形式のコマンドを集めた新しい initrd を用意する
  ことです。新しく initrd を作るには、まず ramdisk 上にファイルシステム
  を作って必要なファイルを集め、それをファイルに書き出すのが簡単でしょ
  う。以下にそのための一つの手順を述べます。

  1. ramdisk 上に 4M ほどの ext2 のファイルシステムを構築する。

     ___________________________________________________________________
     # mke2fs /dev/ram0 4000
     ___________________________________________________________________

  initrd 経由で起動したシステムの場合、/dev/ram0 は使用中の場合がありま
  すので、その際は /dev/ram1 等を使ってください。

  2. ramdisk を適当なディレクトリにマウント。ヒナ型に使うため
     に、pcmciax2 も別のディレクトリにマウントし、いったん pcmciax と同
     じファイルを /workdir 以下にコピーします。

     ___________________________________________________________________
     # mount -t ext2 /dev/ram0 /workdir
     # mount /dos/linux/pcmciax /refdir -o loop,ro
     # cd /refdir; tar cvf - * | (cd /workdir; tar xf -)
     ___________________________________________________________________

  3.  この時点で /workdir 以下は pcmciax2 と同じファイル構成になっている
     ので、 a.out 形式のライブラリやコマンド類を ELF 形式のものに入れか
     えます。このあたりは面倒ですが、手作業でやるしかないようです。

  4. pcmcia-cs を /workdir 以下にインストールします。pcmcia-cs のディレ
     クトリでmake configすると設定に関する質問が表示されますので、
     "Alternate target install directory" で /workdir を指定します。

     ___________________________________________________________________
      # make config

       Linux PCMCIA Configuration Script
       The default responses for each question are correct for most users.
       Consult the PCMCIA-HOWTO for additional info about each option.

       Linux source directory [/usr/src/linux]:
       Alternate target install directory [/]: /workdir
       /workdir
       C compiler name [gcc]:
       ......
     ___________________________________________________________________

  この状態で make all して make install すれば /workdir/etc/pcmcia や
  /workdir/lib/modules/`uname -r`/pcmcia に必要なモジュールがインストー
  ルされます。ただし、/workdir/usr/man 以下に pcmcia-cs のマニュアル類も
  インストールされてしまうので不要ならば削除してください。

  initrd 以外に、起動後に実行される実際のルートファイルシステムにも pcm-
  cia-cs はインストールしておく必要があります。そのためには、 pcmcia-cs
  を再度 "Alternate target install directory : / " に設定してインストー
  ルしておきましょう。

  5.  /dev/ram0 に作成したファイルシステムを通常のファイルに落とします。

     ___________________________________________________________________
     # umount /workdir
     # dd if=/dev/ram0 of=initrd bs=1k count=4000
     ___________________________________________________________________

  6. これで新しい initrd ができました。mount initrd /workdir -o loop と
     して、正しくファイルシステムとして認識できるか確認しておきましょ
     う。

  7. 新しく作った initrd を DOS からアクセスできる領域にコピーします。
     initrd は圧縮しておくことも可能です。

     ___________________________________________________________________
     # cp initrd /dos/linux
     # gzip /dos/linux/initrd
     ___________________________________________________________________

  8. 新しいカーネルと initrd の組み合わせで再起動します。

  手元で試作した initrd を http://www.st.rim.or.jp/~isle/Linux/initrd.gz
  に用意しました。この initrd には、対話的に外付け SCSI をルートファイル
  システムにしたり、 NFS root を指定したりする dialog も付けていますの
  で、興味のある方はお試しください。この initrd に組みこんでいる pcmcia-
  cs は 2.8.23 でカーネル 2.0.27 用にコンパイルしています。

  6.  all-in-one package の作り方

  Slackwareでは色々なデバイスドライバを組みこんだカーネルを用意したファ
  イルシステム(ブートデイスク)とインストール用のファイルシステム(ルート
  ディスク) 2 枚組でインストールします。また、ルートファイルシステムにト
  ラブルが発生した場合などに非常用のツール一式を組みこんだルートファイル
  システム(レスキューディスク)も用意されています。

  しかし、2 枚のディスクが必要な場合、マーフィの法則の典型例として、必要
  な場合にはどちらかのディスクが見当たらなくなるので(単に私に整理能力が
  無いためだろうけど、、)、これらの 2 枚分のデータを 1 枚のフロッピーに
  詰めこんでしまいたくなります。本節では 1 枚の FD から Linux を起動し、
  最小限のシステムが動く環境を構築する方法(all-in-one package)について説
  明します。

  all-in-one package を作る方法としては、通常の ramdisk を使う方法と
  initrd を使う方法の 2 つがあります。ramdisk を使う場合にはさらに lilo
  を経由する方法と経由しない方法があります。これらの方法を順に説明しま
  す。

  6.1.  lilo 経由で ramdisk を使う方法

  ramdisk を使う場合、起動用のファイルシステムを書きこんだ FD の空いてい
  る部分に ramdisk に組みこむためのルートファイルシステムのイメージを書
  きこむことになります。そのためには ルートファイルシステムを圧縮したイ
  メージを /dev/fd0 に書きこむ際に、dd の seek オプションを使ってブート
  ファイルシステムの分だけ後ろにずらしてやる必要があります。

  この方法の利点は lilo 経由で起動するためにカーネルにコマンドラインオプ
  ションを指定したり、複数の設定を切りかえて使えることです。一方、欠点と
  しては mount してディスクの中身を確認する際に root fs の分しか内容が表
  示されず、root fs として何が入っているかを確認するには起動してみるしか
  ないことがあります。

  ここでは Slackware 3.1 に付属の AHA-1542 用ドライバを組みこんだカーネ
  ルに rescue disk のイメージ(rescue.gz)を書きこんで、非常用の root/boot
  フロッピーを作ってみます。

  1. AHA-1542 用の起動用ディスクイメージを dd を使ってフロッピーディスク
     に書きだします。

     ___________________________________________________________________
     # dd if=/cdrom/slackware/bootdsks.144/aha1542.s of=/dev/fd0 bs=1k
     556+0 records in
     556+0 records out
     ___________________________________________________________________

  rescue disk のイメージを boot disk のイメージの後ろに書きこみたいた
  め、 "bs=1k" オプションを指定して、boot disk のイメージがフロッピーの
  どこまでを占めるかを確認しておきます。この例では 1 ブロック 1k として
  556 ブロックまで占めています。

  2. recue disk のルートファイルシステムイメージをフロッピーに追加する。

     dd の seek オプションを使ってブートディスクのイメージと重ならないよ
     う 560 ブロック以降に rescue disk のイメージ(rescue.gz)を追記しま
     す。

     ___________________________________________________________________
     # dd if=/cdrom/slackware/rootdsks/rescue.gz of=/dev/fd0 bs=1k seek=560
     529+1 records in
     529+1 records out
     ___________________________________________________________________

  これで 1 枚の FD にブート用のファイルシステムとルート用のファイルシス
  テムが入りました。

  3. boot disk の /etc/lilo.conf の修正

     次に、起動時に ramdisk を読みこむように boot disk の /etc/lilo.conf
     を修正します。このためには /dev/fd0 をどこか適当なディレクトリに
     mount する必要があります。以下では /workdir にマウントしています。

     ___________________________________________________________________
     # mount /dev/fd0 /workdir
     # df
     Filesystem         1024-blocks  Used Available Capacity Mounted on
     /dev/hda3             944303  747325   148191     83%   /
     /dev/hda1             308248  267832    40416     87%   /dos
     /dev/fd0                 539     490       49     91%   /workdir
     #
     ___________________________________________________________________

  この方式で作った all-in-one ディスクをマウントした場合、認識されるのは
  このようにブートディスクの部分だけです。

  もともとの lilo.conf はこのようになっているはずです。

  ______________________________________________________________________
  # cat /workdir/etc/lilo.conf
  boot = /dev/fd0
  message=/boot/message
  prompt
  image = /vmlinuz
          label = ramdisk
          ramdisk = 49152
          root = /dev/fd0u1440
          vga = normal
  image = /vmlinuz
  (後略)
  #
  ______________________________________________________________________

  この /workdir/etc/lilo.conf を修正して、起動時に自動的に ramdisk を読
  みこむようにします。ramdisk 用にカーネルのコマンドラインとして以下のよ
  うなパラメータが用意されています。

     o  ramdisk_start

        FD 上で ramdisk が開始するブロックを指定します。今回の例では 560
        です。

     o  load_ramdisk

        ramdisk をロードする(1)かしない(0)かの指定です。今回は 1 を指定
        して、 ramdisk をロードするようにします。

     o  ramdisk_prompt

        ramdisk をロードする際にプロンプトを出す(1)か出さない(0)かの指定
        です。 FD が 2 枚組になっている場合は FD を入れかえるためにプロ
        ンプトを出しますが、all-in-one の場合はプロンプトを出す必要はな
        いので 0 を指定します。

     o  ramdisk_size

        必要な ramdisk のサイズです。デフォルトでは 4096k になっており、
        このサイズを超える ramdisk を確保したい場合やメモリの少ないマシ
        ンで ramdisk のサイズを切り詰めたい場合に指定します。今回は特に
        指定する必要はありません。

  以上のことから、今回は lilo.conf に "ramdisk_start=560 load_ramdisk=1
  prompt_ramdisk=1" という指定を追加すればいいことが分ります。これらのオ
  プションは lilo.conf に "append = " という形で記述します。

  ______________________________________________________________________
  boot = /dev/fd0
  message=/boot/message
  append="ramdisk_start=560 load_ramdisk=1 prompt_ramdisk=0"
  prompt
  image = /vmlinuz
          label = ramdisk
          root = /dev/fd0u1440
          vga = normal
  ______________________________________________________________________

  4. /sbin/lilo を実行して、MBR の設定

     lilo.conf を修正すると、一度 /sbin/lilo を実行して、設定情報を MBR
     に反映させる必要があります。lilo は -r オプションでディレクトリを指
     定すると、そのディレクトリに chroot して実行されます。今回の例では
     /workdir に /dev/fd0 がマウントされているので、 /workdir を指定して
     /workdir/etc/lilo.conf の設定を反映するように lilo を実行します。

     ___________________________________________________________________
     # /sbin/lilo -r /workdir
     Added ramdisk *
     Added big2
     Added small2
     Added drive2
     Added mount
     #
     ___________________________________________________________________

  これで all-in-one の boot/rescue ディスクができました。システムを FD
  から立ちあげて、自動的に ramdisk がロードされ、rescue disk が起動する
  ことを確認してください。

  6.2.  zdisk で ramdisk を使う方法

  lilo を使って起動する場合、lilo の出す boot: プロンプトに対して必要な
  オプションを指定することができるので、さまざまな状況に対応することがで
  きます。一方、この方法では、起動用にファイルシステムが必要となり、使用
  するディスクスペースも大きめになります。

  一方、Linux の make zImage で作成されるカーネルイメージには FD から自
  分自身を起動するためのコードが付いているので、lilo のオプション指定を
  する必要がない環境では lilo を使わずに直接 FD からカーネルを起動するこ
  とも可能です。ただし、この機能を使って ramdisk をロードするためには
  rdev というコマンドを使ってカーネル自身にルートファイルシステムのデバ
  イス名や ramdisk の位置、 ramdisk のロードの有無を書きこんでおく必要が
  あります。

  この方法の利点は boot disk にファイルシステムが不要でカーネルイメージ
  を直書きすればいいだけになるので、FD の使用量が少なくできることです。
  一方、欠点としては、カーネルが直接起動してしまうのでコマンドラインオプ
  ションを指定できないことです。そのためこの方法で 1FD router を作ること
  はできません(ルータを作る場合、複数の ethernet カードを認識させる必要
  があるので、カーネルオプションが必須です)

  また作成したフロッピーの中身を確認する方法がない(これで作った /dev/fd0
  はファイルシステムとしてマウントできません)ことも欠点と言えるでしょ
  う。

  1. AHA-1542 用のカーネルイメージを FD に書きこむ。

     前節と同様に AHA-1542 用のドライバを組みこんだカーネルを使います
     が、今回書きこむものはファイルシステムではなくカーネルそれ自身なの
     で、必要なファイルは /cdrom/slackware/kernels/aha1542.s/zImage にな
     ります。

     ___________________________________________________________________
     # dd if=/cdrom/slackware/kernels/aha1542.s/zImage of=/dev/fd0 bs=1k
     437+1 records in
     437+1 records out
     #
     ___________________________________________________________________

  ファイルシステムを書きこんだ場合、530 ブロック必要でしたが、カーネルだ
  けを書きだすと 440 ブロックほどで済んでいることが分ります。

  2. rescue disk のイメージを FD に追加する。

     カーネルは 440 ブロックぐらいで収まっているので、rescue.gz は 450
     ブロック以降に書きこみましょう。

     ___________________________________________________________________
     # dd if=/cdrom/slackware/rootdsks/rescue.gz of=/dev/fd0 bs=1k seek=450
     529+1 records in
     529+1 records out
     #
     ___________________________________________________________________

  3. rdev でカーネル自身に必要な情報を設定

     lilo の場合、カーネルにコマンドラインパラメータを使って ramdisk に
     関する設定を行えましたが、今回は lilo を経由しないのでカーネル自身
     に必要なパラメータを書きこんでしまう必要があります。そのために使う
     コマンドが rdev です。まず、rdev コマンドで /dev/fd0 にあるカーネル
     のルートデバイスを /dev/fd0 に書きかえておきます。

     ___________________________________________________________________
     # rdev /dev/fd0 /dev/fd0
     ___________________________________________________________________

  rdev ではカーネル内部の 1 word(2 bytes)の領域を直接書き替えることで
  ramdisk のロードの有無や ramdisk の位置を変更できます。

  rdev で指定する 2 bytes のうち、下位 11 bit(0 bit -> 10 bit) は
  ramdisk の位置を指定するために使われ(1k 単位のオフセット情報)、14 bit
  目が ramdisk のロードの有無、15 bit 目が ramdisk をロードする際のプロ
  ンプトの有無の指定です。

  今回の例では、ramdisk をロードし(bit 14 on)、ramdisk をロードする際に
  プロンプトは不要(bit 15 off)、ramdisk のオフセットは 440 ブロックにな
  りますので、

  2^15*0(prompt) + 2^14*1(ramdisk) + 440(offset) = 16824 を rdev で設定
  します。同時に rdev -R オプションを使ってルートファイルシステムを r/w
  でマウントするように設定します。

  ______________________________________________________________________
  # rdev -r /dev/fd0 16384
  # rdev -R /dev/fd0 0
  ______________________________________________________________________

  これで、直接起動用の boot/root フロッピーができました。システムを再起
  動して、rescue disk が正しく機能するか確認してください。

  6.3.  initrd を使う方法

  initrd を使う方法の利点は、ロードする ramdisk のあるファイルシステムを
  圧縮ファイルとして直接指定できるので、FD の中に見えない領域が無くなる
  ことです。私のように整理能力の無い人間にはどの root fs イメージが入っ
  ているのか確認してから起動できるこの方式がもっとも安心できます(笑)。ま
  た、FD 全体の使用量が見えるので、あとどれくらいの機能を組みこめるかを
  検討する際にも便利です。

  一方、この方法の欠点としては、Slackware 3.1 に付属のカーネルイメージに
  は initrd 機能は組みこまれていないので、このためのカーネルは手元で
  initrd 機能を組み込んでコンパイルしなければならないことです。また、
  rescue.gz もそのままでは initrd として使えないため、少し細工をしてやる
  必要があります。

  1. 手元でカーネルのコンパイル

     必要なオプションを組みこんでカーネルを設定し、make zImage しておき
     ます。オプションを選ぶ際に、ramdisk 機能と initrd 機能は忘れずにカ
     ーネルに組みこんでください。

     ramdisk 機能はモジュール化できますが、モジュールではなくカーネルに
     組みこむ必要があります。

  2. 起動用の FD の準備

     この方式では FD 1 枚に 1 つのファイルシステムを作って、そこに boot
     fs と initrd 用の圧縮したファイルシステムを置くことになります。FD
     にファイルシステムを作る際は ext2fs よりも minix fs にした方が容量
     を効率よく使えます。状況によっては -i オプションを使って i-node を
     増しておいた方がいいかも知れません。

     ___________________________________________________________________
     # mkfs.minix /dev/fd0 1440
     480 inodes
     1440 blocks
     Firstdatazone=19 (19)
     Zonesize=1024
     Maxsize=268966912
     #
     ___________________________________________________________________

  3. FD に必要なファイルのコピー

     この FD を起動用に使うには /dev や /etc 以下のファイルが必要です
     が、それらはSlackware のブートディスクのイメージをコピーするのが簡
     単でしょう。そのために /dev/fd0 を /workdir
     に、/cdrom/slackware/bootdsk.144/aha1542.s を /mnt にそれぞれマウン
     トし、tar を使ってブートディスクのイメージを FD にコピーします

     ___________________________________________________________________
     # mount /dev/fd0 /workdir
     # mount /cdrom/slackware/bootdsk.144/aha1542.s /mnt -o loop
     # df
     Filesystem         1024-blocks  Used Available Capacity Mounted on
     /dev/hda3             944303  747372   148144     83%   /
     /dev/hda1             308248  267832    40416     87%   /dos
     /cdrom/slackware/bootdsk.144/aha1542.s
                              539     490       49     91%   /mnt
     /dev/fd0                1404       1     1403      0%   /workdir
     #
     # cd /mnt
     # tar cvf - * |(cd /workdir; tar xf -)
     # sync
     # df
     Filesystem         1024-blocks  Used Available Capacity Mounted on
     /dev/hda3             944303  747372   148144     83%   /
     /dev/hda1             308248  267832    40416     87%   /dos
     /cdrom/slackware/bootdsk.144/aha1542.s
                              539     490       49     91%   /mnt
     /dev/fd0                1404     490      914     35%   /workdir
     # ls -l /workdir
     total 446
     drwxr-xr-x   2 root     root          160 Jun 13  1996 boot
     drwxr-xr-x   2 root     root         3632 May 20  1996 dev
     drwxr-xr-x   2 root     root           48 May  8  1995 etc
     drwxr-xr-x   2 root     root           32 Mar 10  1993 proc
     -rw-r--r--   1 root     root       448013 Jun 13  1996 vmlinuz
     #
     ___________________________________________________________________

  この時点での /workdir/vmlinuz は initrd の機能が組みこまれていないカー
  ネルなので、手元でコンパイルした zImage(あるいは bzImage) ファイルを
  vmlinuz に置きかえます。

  ______________________________________________________________________
  # cp /usr/src/linux/arch/i386/boot/zImage /workdir/vmlinuz
  ______________________________________________________________________

  4. initrd の準備

     initrd で使うためには rescue.gz に linuxrc というファイルを作る必要
     があります(linuxrc の実体はbin/sh へのシンボリックリンクで構いませ
     ん)。このためには一度 rescue.gz を展開してファイルとしてマウントす
     る必要があります。

     ___________________________________________________________________
     # gunzip < /cdrom/slackware/rootdsks/rescue.gz > /tmp/rescue
     # mount /tmp/rescue /tmpmnt -o loop
     # cd /tmpmnt
     # ln -s bin/sh linuxrc
     # cd /
     # umount /tmpmnt
     # gzip -9 < /tmp/rescue > /workdir/rescue.gz
     ___________________________________________________________________

  5. /etc/lilo.conf の設定

     /workdir/etc/lilo.conf を修正して、initrd として rescue.gz を使うよ
     うにします。initrd を使う場合、lilo.conf に "initrd = filename" と
     いうオプションを追加します。私はこういう風にしてみました。

     ___________________________________________________________________
     boot = /dev/fd0
     message=/boot/message
     prompt
     image = /vmlinuz
             label = ramdisk
             initrd = /rescue.gz
             vga = normal
     ___________________________________________________________________

  lilo.conf を設定すれば、lilo を再実行して、変更点を反映させます。

  ______________________________________________________________________
  # /sbin/lilo -r /workdir
  Added ramdisk *
  #
  ______________________________________________________________________

  これで initrd を使った all-in-one disk ができました。システムを再起動
  して正しく機能するか確認してみてください。この例では ctrl-D や exit で
  linuxrc を終了させる前に、本文書中で説明した方法で実際のルートファイル
  システムを設定しておく必要があることに御注意ください。

  7.  関連文書

  この文書を書く際に参考にした文書は、 /usr/src/linux/Documentationディ
  レクトリにある initrd.txt と nfsroot.txt 、ramdisk.txtです。これ以外に
  も、loadlin16 distribution 中の docs/manuals.txt に initrd についての
  説明があり、LDP の HOWTO 集の中にも nfs-root-mini-HOWTO があります(邦
  訳あり)。

  8.  おわりに

  initrd はここで示した以外にもさまざまな使い方があるシステムだと思いま
  す。何かおもしろい活用方法を思いついた方はぜひ教えてください。

  例えば、pcmciax.gz と aha1542 用のカーネルを一枚の FD に詰めこんだ
  all-in-one boot/root ディスクと MO なり CD-ROM なりにルートファイルシ
  ステムを書きこんだものを用意すれば、SCSI 機器のつながった NotePC を
  「お手軽 Linux マシン」に変身させることが可能でしょう。また、NFS 環境
  ならば FD 1 枚の「お手軽 Diskless Linux マシン」キットというのも面白い
  かも知れません。

  多分 RedHat や Debian でも似たようなことはできるはずですが、Red Hat を
  少しいじった限りでは、システムとしての完成度が高い分、こういう変ったこ
  とをするには自由度が低いようです。もちろん、いったん起動してしまえば、
  ルートファイルシステムは Red Hat でも debian でも関係ないはずですが。

  間違いや誤字・脱字、改善のアイデアなど、なんでも 筆者まで御連絡いただ
  けば幸いです。

