現在の Linux カーネルには、 root ディスクを自動的に RAM ディスクにコピー する機能があります。このとき root ディスクのファイルシステムは minix か ext2 である必要があります(お薦めは ext2 です)。 ext2 ファイルシステムへの対応はカーネルバージョン 1.1.17 - 1.1.57 あた りで行われました。この範囲のバージョンのカーネルをお持ちの場合、 /usr/src/linux/drivers/block/ramdisk.c の内容を見て "ext2" という単語を探して下さい。もし見つからなければ minix ファイルシステムが唯一の選択肢となります。minix ファイルシステム を作成するには "mkfs" コマンドを用います。
ext2 をお使いの場合は -i オプションを指定してデフォルトより多くの i ノー ドを作っておくと良いでしょう。 -i 2000 としておけば i ノードを使い切る 心配はしなくてすむでしょう。または /dev から不必要なファイル(ほとんど が不要でしょう)を消去しておきましょう。デフォルトの場合 mke2fs は 1.44 メガのフロッピーに 360 個の i ノードを作ります。 今私のレスキュー ディスクを見てみたら 120 個の i ノードが余っていました。しかし /dev ディ レクトリのファイルを含めると 360 個は簡単に越えてしまうでしょう。圧縮 形式のルートファイルシステムを用いるとファイルシステムの大きさが増えま すから、デフォルトの i ノードの数も 360 以上になります。でも依然ファイ ルを減らすか i ノードを増やすかする必要があるでしょう。
ext2 ファイルシステムをフロッピー上に作成するには以下のコマンドを使います。
mke2fs -m 0 /dev/fd0
mke2fs コマンドは自動的に利用可能な容量を検知してファイルシステムの設 定を行います。したがって引数は必要ありません。お望みなら mke2fs の作業 時間を短縮するためにディスクのサイズを 1K バイトブロックの個数で指定す ることもできます。 -m 0 パラメータを利用するとスーパーユーザのための予 約領域を作らなくなるので、利用できるディスク領域が増えます。
上のようなコマンドでファイルシステムを作った後、結果を検査するにはフロッ ピーをマウントしてみるのが簡単です。 ext2 ファイルシステムを作成した場 合は
mount -t ext2 /dev/fd0 /<mount point>
とすれば良いでしょう。
多くの場合は現在使用しているカーネルをブートディスクにコピーすれば、そ のフロッピーディスクからブートができます。しかし現在使用しているカーネ ルとは別のカーネルをブートディスク用に作成したい場合もあります。
ひとつの理由はカーネルの大きさです。最小構成のシステムではカーネルは最 も大きなファイルのひとつですから、 boot/root フロッピーを作成する場合 にはカーネルの大きさをできる限り小さくする必要があります。現在のカーネ ルでは、ブート後ルートファイルシステムをマウントする前にフロッピーの交 換ができるので、カーネルを別のディスクに置いておくことができます。した がってこの節の情報は boot/root フロッピーを作らない場合はあまり有用で はありません。
カーネルの大きさを削るには以下の二つの方法があります:
make zImage
圧縮カーネルの作成に関する最新の情報はカーネルのソースに付属の文書を参
照して下さい。カーネルのソースは通常 /usr/src/linux にあります。
最小限の機能を持つカーネルを作成したら、次にどの機能をカーネルに戻して いくかを決めます。 boot/root フロッピーはルートファイルシステムを検査、 修復するために用いられることが多いでしょうから、これを行えるような機能 をカーネルに加える必要があるでしょう。
例えば Ftape を用いてテープにバックアップを取ってあった場合、現在のルー トドライブと Ftape コマンドを含むドライブを壊してしまったら、 バックアップテープからの修復は不可能になってしまいます。 Linux を再イ ンストールし、 Ftape を取って来て再インストールした後でバックアップを 読み込まなければならなくなります。
また、バックアップを取るのに使ったプログラムについては、同じバージョン のコピーを用意し ておくと良いでしょう。そうすればバックアップテープの読めないバージョン をインストールして、時間を無駄にしたりすることがなくなります。
要するにバックアップを取るために用いた I/O 機能は全て boot/root カーネルにも加える必要があるということです。
実際にカーネルを構築する手順についてはカーネルに付属の文書に記述してあ ります。非常に簡単ですから、/usr/src/linux ディレクトリの中を調べるこ とから始めて下さい。カーネルを構築できない人は、 boot/root フロッピー を作るのをあきらめた方がいいでしょう。
/dev ディレクトリは全ての Linux システムに必須のディレクトリで、システ ムが使う全てのデバイスに対するスペシャルファイルがここにあります。 /dev 自身は普通のディレクトリで、ごく普通に mkdir コマンドで作成できます。 しかしデバイスのスペシャルファイルは特別な方法( mknod コマンド)を用 いて作成しなければなりません。
でも近道もあります。既に存在する /dev ディレクトリの内容をコピーして、
不要なものを消去するのです。注意しなければいけない点は、デバイスのスペ
シャルファイルをコピーする場合には -R オプションが必要だ、ということく
らいです。
cp
コマンドには -R
の機
能がありません。
-R オプションを指定すると、ファイルの内容はコピーせずにディレクトリが コピーされます。小文字の "-r" オプションを使うと全く異なっ た動作となります。ハードディスクの内容が(少なくともフロッピーが一杯に なるまで)全部コピーされます!ですから次のコマンドを使うときはオプショ ンに注意して下さい。
cp -dpR /dev /mnt
ここでフロッピーは /mnt にマウントされているとしています。 d オプションは
シンボリックリンクをコピーする際に、リンク先の実体ではなくリンクそのも
のをコピーするための指定です。 p オプションは元のファイルの属性を保存
します(したがって所有者情報も保存されます)。
cpio の -p オプションを使うこともできます。 cpio はデバイスのスペシャ ルファイルを正しく扱うことができます(ファイルの中身をコピーしません)。 例を挙げます。
cd /dev
find . -print | cpio -pmd /mnt/dev
こうすればデバイスのスペシャルファイルが /dev から /mnt/dev へコピーさ れます。実際には /dev から下のディレクトリツリーを全部コピーするので、 /dev にサブディレクトリがある場合は /mnt/dev にもサブディレクトリが作 成されます。
手間のかかる方法でやりたい場合は、 ls -l でコピーしたいデバイスのメジャー 番号、マイナー番号を調べて、 mknod コマンドでフロッピー上にそれらを作 成します。
多くの配布パッケージの /dev ディレクトリには MAKEDEV というシェルスク リプトがあります。これを用いてデバイスファイルを作成することも可能です が、既存のデバイスファイルを単純にコピーする方がレスキュー用のディスク を作る場合には簡単でしょう。
どんな方法であれ、ディスクに /dev ディレクトリを作った後には、必要なデ バイスファイルがちゃんと含まれているかを確認しておきましょう。例えば Ftape はテープデバイスを使いますから、テープのデバイスファイルは全て コピーしておく必要があります。
それぞれのデバイスファイルにひとつづつ i ノードが必要です。フロッピー のファイルシステムでは i ノードは不足しがちですから、必要でないデバイ スファイルをフロッピーから消しておくと良いでしょう。明らかに不必要なデ バイスが結構あるはずです。例えば SCSI ディスクを持っていないのなら "sd" ではじまる名前のファイルは全て消すことができます。同 様にシリアルポートを使わないつもりなら "cua" ではじまるファ イルも消せます。
/dev、 /proc、 /etc だけで Linux システムを動作させることも可能かもし れませんが、私は良く知りませんし試したこともありません。でも共有ライブ ラリの置き場がないので全部のバイナリをスタティックリンクしておかなけれ ばいけませんからきっと難しいでしょうね。現実的な最小のディレクトリ構成 は以下のようになります。
デバイスへの I/O に必要
ps コマンドに必要
システム設定ファイルが含まれる
システムの一部と見なされるプログラムが含まれる
プログラム実行に必要な共有ライブラリが含まれる
他のディスクを使う時のマウントポイント
追加分のプログラムとアプリケーション
ここに示されたディレクトリ構造は root フロッピーのためのものです。「通 常の」 Linux システムでのファイルシステム構成に関する情報は "Linux File System Standard" を参照して下さい。
上記のディレクトリの内4つは非常に簡単に作成できます。
残りの 3 つのディレクトリについては以下の節で説明します。
このディレクトリには多くの設定ファイルが必要です。大抵のシステムではこ れらは以下の3つに分けられます。
必要でないファイルは以下のコマンドで見つけることができます。
ls -ltru
このコマンドでファイルは最後にアクセスされた日の逆順に一覧表示されます
から、アクセスの無かったファイルを見つけて root フロッピーから取り除く
ことができます。
私の場合 root フロッピーに入れる設定ファイルの数は下記の15個にまで減ら すことができました。以下 3 つの種類に分けて説明します。
システムのスタートアップとランレベルの変更に用いるス クリプト
マウントするファイルシステムの一覧
init プロセス(ブート後最初に起動されるプロセス)のパラ メータファイル
ログインするユーザの一覧
パスワードを保持しているファイル
この中で本当に設定しなければならないのは 2 個のファイルだけです。その 中身はとても小さいです。
#!/bin/sh
/etc/mount -av
/bin/hostname boot_root
hostname は必ずしも実行する必要はありません。単に見た目を良くするため
だけのものです。 mount も実際には ps コマンドを利用するために /proc を
マウントしているだけです。 /proc ファイルシステムが無くても Linux は動
作しますが、レスキュー作業を行なうときにはあった方が良いでしょう。
/dev/ram / ext2 defaults
/dev/fd0 / ext2 defaults
/proc /proc proc defaults
1 行目の記述は不必要だと思うんですが、これを削除するとなぜか mount コ
マンドは /proc をマウントしなくなります。inittab はシリアルポートからの login を禁止したくないならそのままで OK です。シリアルポートからの login を禁止するには、 inittab に含まれる /etc/getty のエントリのうち行末が ttys または ttyS デバイスになってい るものを全部コメントアウトします。 tty のエントリはコンソールから login できるように残しておきます。
inittab はスタートアップやマルチユーザモードへの移行、電源断のときなど に、どのようなシステムを起動(あるいは再起動)するかを定めるものです。 ここで特に注意しておきたい点は、 inittab で指定されているコマンドは必 ず正しいディレクトリに存在しなければならないということです。この文書に 載っている例をもとにディレクトリを作成し、あなたの現在使っているシステ ムから inittab をコピーすると、 inittab で指定しているプログラムがなかっ たり、ディレクトリが違っていたりというミスを犯す危険性が非常に高くなる でしょう。
決まったディレクトリに置いておかなければならないプログラムもあります。
これらのプログラムを実行する他のプログラム中に、ディレクトリを含めたパ
スがハードコーディングされていることがあるからです。例えば私のシステム
では、
/etc/shutdown
プログラムには /etc/reboot
が書き込ま
れています。もし reboot を /bin/reboot に移してしまうと、 shutdown は
reboot ファイルを見つけられないので起動できなくなります。
残りのファイルについては /etc ディレクトリにある全てのテキストファイル を単にフロッピーにコピーするだけです。加えて /etc ディレクトリにある実 行ファイルのうち、不要だという自信の無いものを全てコピーします。 root ディスクのディレクトリ一覧 の節が役に立つでしょう。これは私のディスクのディレクトリの一覧です。こ のままでうまく行くこともありますが、システムはそれぞれ大きく異なるのが 普通ですから、当然うまく行かない場合もあり得ます。確信を持ちたい場合に は inittab から辿って必要なファイルを全部確認するほかありません。
現在ほとんどのシステムでは、実行レベルごとに異なるシェルスクリプトの 置き場所として /etc/rc.d ディレクトリを使っています。とにかく小さくし たい場合には rc スクリプトひとつだけにすることもできますが、実際には今 のシステムから inittab と /etc/rc.d ディレクトリをコピーして、フロッピー ベースのシステムに不要なものを削っていく方がずっと簡単でしょう。
このディレクトリには ls や mv、 cat、 dd などの基本的な操作を行うとき に必要なコマンドを置いておくと良いでしょう。
root ディスクのディレクトリ一覧 の節には私の boot/root フロッピーの /bin の一覧があります。私の /bin ディレクトリには cpio、 tar、gzip といったバックアップを復旧するために 必要なプログラム群が置いてありません。これらは boot/root フロッピーの 空き領域を増やすために別のフロッピー(utility ディスク)に入れて あるからです。いったん私の boot/root フロッピーを使ってブートすると、 このフロッピーの内容は自動的に RAM ディスクにコピーされます。その後 utility ディスクをマウントして使います。私は utility ディスクを 普通 /usr にマウントしています。
utility フロッピーの作成方法は utility ディスク の節に記述してあります。
/lib には必要な共有ライブラリとローダを置きます。必要な共有ライブラリ が /lib になければシステムをブートすることはできません。運が良ければエ ラーメッセージで何が足りないかがわかるでしょうが。
ほとんど全てのプログラムは、少なくとも libc ライブラリを必要とします。
libc.so.X
X はバージョン番号です。ご自分の /lib ディレクトリを見て下さい。 libc.so.4 はバージョン番号のついた他のファイルへのシンボリックリ ンクになっていると思います。
ls -l /lib
と実行すれば、
libc.so.4 -> libc.so.4.5.21
のような表示が出るでしょう。
この場合必要なライブラリは libc.so.4.5.21 ということになります。今のは あくまで例です。 ELF の libc ライブラリは現在 libc.so.5.xxxx になって います。
他に必要なライブラリを探すには、ディスクで使うつもりのバイナリ全てにつ いて、依存しているライブラリをチェックする必要があります。これには ldd コマンドを使います。例えば私のシステムでは、
ldd /bin/mount
とすると以下のような結果になります。
/bin/mount:
libc.so.5 => /lib/libc.so.5.2.18
この結果を見ると /bin/mount には libc.so.5(実際には libc.so.5.2.18 へ
のシンボリックリンク)が必要なことがわかります。
/lib にはライブラリをロードするためのローダも入れる必要があります。ロー ダのファイルの名前は ld.so (a.out ライブラリ用)または ld-linux.so (ELF ライブラリ用)です。どちらが必要かわからなければ、ライブラリファ イルに対して file コマンドを実行して下さい。私のシステムでの例を挙げま す。
file /lib/libc.so.5.2.18
結果は以下のようになります。
/lib/libc.so.5.2.18: ELF 32-bit LSB shared object ...
したがってこのファイルには ELF のローダが必要だということがわかります。
a.out のライブラリをお持ちの場合には、代わりに以下のような表示が出ます。
/lib/libc.so.4.7.2: Linux/i386 demand-paged executable (QMAGIC) ...
必要な方のローダをコピーして下さい。両方とも必要な場合もあるかもしれません。
ライブラリとローダが使用するプログラムに対応しているか、厳重にチェック して下さい。必要なライブラリがロードできないと、通常カーネルはエ ラーメッセージを出すこともなくハングアップしてしまいます。
boot/root ディスクはブート可能でなければなりません。これを可能にする最 も簡単な方法はブートローダをインストールすることです。ブートローダとは フロッピーディスクのセクタ 0、シリンダ 0 に書き込まれる実行プログラム のことです。ブートプロセスについての概要は boot ディスク の節の 概要 をご覧下さい。
LILO は良くテストされた信頼できるブートローダで、 Linux のミラーサイト でしたらどこからでも入手できます。 LILO を使うと以下のような設定が可能 になります。
LILO を用いると、カーネルのブート方法を非常に柔軟に設定できます。私の root/boot フロッピーでの LILO の設定ファイルを示します。 LILO のバージョ ンは 0.15 です。
boot = /dev/fd0
install = ./mnt/boot.b
map = ./mnt/lilo.map
delay = 50
message = ./mnt/lilo.msg
timeout = 150
compact
image = ./mnt/zImage
ramdisk = 1440
root = /dev/fd0
実は私は LILO ベースの boot/root フロッピーを使わなくなってしまったの で、この設定ファイルは最近はテストしていません。この設定で動かない理由 は特にないはずですが、うまく行かない場合は LILO のドキュメントを見て理 由を探して下さい。
また 1.3.48 以降のカーネルを用いれば、圧縮されたルートファイルシステム をカーネルと同じディスクに置き、ロードして用いることができます。ですか ら boot/root システムに LILO を使わなければならないという制約はもうあ りません。詳細については ブートディスク作成上級編 の章を参照して下さい。
1.3.48 以降のカーネルを使っている方は "ramdisk = 1440" の行は不要ですから、削っておく方が良いでしょう。
boot.b、 lilo.msg、 そしてカーネルは全てに先立ってフロッピーにコピーし ておく必要があります。以下のようなコマンドを用います。
cp /boot/boot.b ./mnt
もしこの作業が行われていない場合、ハードディスクが利用できる場合を除い て LILO はブート時に正しく動作しません。ハードディスクが無ければブート できないレスキューディスクを作ってもしょうがないですよね。
以下のように lilo を実行します。
/sbin/lilo -C <configfile>
このコマンドはフロッピーをマウントしたディレクトリの親ディレクトリで実 行する必要があります。このコマンドを実行すると LILO はブートローダをブー トデバイス(この場合 /dev/fd0)にインストールし、フロッピーのルートディ レクトリにあるカーネルをブートさせるようにします。
設定ファイルでは 1K バイトのブロック 1440 個からなる RAM ディスクを作成 するような指定もしています。このラムディス クの容量はフロッピーの容量と同じです。この例ではフロッピー上に ext2 の ファイルシステムを作成しましたから、この作業によってブート後にルートデ バイスは自動的に RAM ディスクに切り替わり、フロッピーの内容は全てラムディ スクにコピーされます。
Linux の RAM ディスクの機能については RAM ディスクとフロッピーのルートファイルシステム に詳しい記述があります。
Linux をシングルユーザモードで起動するために "single" パラメータを使うのも悪くありません。この指定をするとシリアルポートから の login を防ぐことができます。
私は "delay"、 "message"、 "timeout" の各パラメータを使っています。これによりディスクからブー トする時に LILO のコマンドラインオプションの指定ができるようになります。 今は必要ありませんが、いつ異なったルートデバイスを指定したり、ファイル システムを書き込み禁止でマウントしたくなるか分かりませんので、LILO を この設定にしてあります。
私の使っているメッセージファイルです。
Linux Boot/Root Diskette
========================
Enter a command line of the form:
zImage [ command-line options]
If nothing is entered, linux will be loaded with
defaults after 15 seconds.
これは自分が設定した内容の備忘録になっています。
導入前に LILO に付属の文書を注意深く読むことをお勧めします。 "boot " パラメータの設定を間違えると、パーティションは簡単 に壊れてしまいます。十分に経験を積んでいない方は、設定ファイルを完全に 理解し、 3 回引数を確認するまでは LILO を絶対に起動しないで下さい。
LILO はカーネルを変更するたびに実行させる必要があります。すると LILO はマップファイルに新しいカーネルを書き込みます。実はほとんど同じカーネ ルに書き換えた場合は LILO を実行しなくても良いのですが、わざわざ危険を 犯す必要は全くないでしょう。 LILO を再実行して下さい。
ここで LILO の話題をもう一つ。もし LILO のブートセクタをすっかりお釈迦 にしてしまっても、それが DOS のドライブにあれば以下の DOS コマンドを実 行すればブートセクタを DOS のブートローダで置き換えることができます。
FDISK /MBR
ここで MBR は "Master Boot Record" を意味します。純粋な Linux 教徒 の中にはこの方法に賛成しない人もいますし、それなりの根拠もあるようですが、 ともかくこの方法でうまくいきます。
LILO にはブートディスクを作成する際に覚えておくと便利なオプションが他 にもいくつかあります。
zImage aha152x=0x340,11,3,1 ro
とすると、カーネル構築時に組み込んだ aha152x scsi ホストアダプタのドライバ
にパラメータを渡し、ルートファイルシステムを読み出し専用にします。
zImage aha152x=0x340,11,3,1 root=/dev/sda8 ro lock
APPEND = "aha152x=0x340,11,3,1"