rescue cdromを作ってみる

linux kernelの肥大化はとどまることを知らず、もはやフロッピーディスクに収まり切るサイズをはるかに越えてしまいました。当然、rescue diskの作成は困難な状況となり、今やrescue systemのメインはcdromです。そんなわけで、ここではオリジナルのrescue cdromを作成してみます。

ここで作成するのは、ram diskをルートファイルシステムとする自己完結的なシステムです。ここでは、最近の状況を考えて、ram diskは64MBに設定しており、使用する機種の搭載メモリは256MB程度を想定しています。

また、このページでは、rescue systemの実験を円滑に行うため、仮想マシンqemuによる実験環境の構築を紹介します。このページの最終目標は、この実験環境において rescue bootし、ホストマシンと仮想マシンをネットワークで繋ぐことです。

ここで作成するrescue cdromは、ル−トファイルシステムも自前で用意するので、言わばオリジナルのミニディストリビューションに他なりません。これは、Linuxをさらに理解するための最適な教材になるのではないかと思います。

このページは、Vine Linux 3.2で検証されています。

1. rescue bootの概要
2. boot loader isolinuxとlilo
3. 実験環境の構築 qemuのインストール
4. initrdの作成
5. ルートファイルシステムの作成
6. rescue cdromの作成
7. 起動実験、設定の変更、カスタマイズ
8. まとめ

1. rescue bootの概要

大雑把に言って、PC/AT互換機におけるLinuxのbootは以下の三段階に分けられます。

i. BIOSが適切なメディアからkernelをロ−ドする。

ii. initrdが設定されている場合はkernelがinitrdをロ−ドし、initrd中のlinuxrcが実行される。

iii. kernelがル−トファイルシステムをmountし、/sbin/initを実行する。

ここで作成するrescue cdromのル−トファイルシステムはram disk上にあることになっているので、iiiでル−トファイルシステムをmountする以前にル−トファイルシステムが存在するram diskを用意する必要があります。つまりiiのinitrdにおいてその作業を行わねばなりません。通常のbootでは、ル−トファイルシステムが存在 するストレ−ジデバイスのmoduleをinitrdでinsmodし、デバイスとして認識させるだけでその作業が完了しますが、仮想のストレ−ジデ バイスであるram diskの場合は、initrdの行程でル−トファイルシステムそのものを作成する必要があります。

このぺ−ジの主題はrescue cdromですので、ram disk上に展開するル−トファイルシステムのオリジナルも当然cdrom上に存在します。つまり、initrdの段階においてkernelは、linuxrcを実行することによってcdromをmountし、cdrom上にあるル−トファイルシステムをram diskに書き込み、ル−トファイルシステムを作成します。ル−トファイルシステムが正しく作成されてしまえば、後は通常の起動とほとんど同様 です。


2. boot loader isolinuxとlilo
以前、cdrom bootはフロッピ−ディスクエミュレ−ションにより行われていました。つまり、cdromからbootしていてもフロッピ−ディスクからbootしているのと同義でした。この方法では、cdromからのbootもフロッピ−ディスクからのbootも同様に扱える利点がありましたが、昨今のブ−トフロッピ−が作れなくなった問題とまったく同様の問題を引き起こします。そういうわけで、昨今はフロッピ−ディスクエミュレ−ションは用いられず、cdromからのノ−エミュレ−ションによるbootが主流になりました。cdromからのノ−エミュレ−ションによるbootは、当然、フロッピ−ディスクの仕様に存在する制限とは無縁です。

かつてLinuxのboot loaderと言えばliloでしたが、liloはcdromのノ−エミュレ−ションbootには対応していないので昨今の巨大なkernelをcdromからbootさせることができません。ですので、ここでのboot loaderは、syslinuxのisolinuxを使用し、rescue cdromを作成します。

ところで、liloはcdromのノ−エミュレ−ションbootには対応していないのですが、実は昨今の巨大なkernelでもliloを用いてcdromからbootすることが可能です。これはフロッピ−ディスクからboot可能であることと同義であり、ここまでの議論と矛盾するかのように思われますが、BIOSおよびフロッピ−ディスクの仕様を良く見てみるとその理由が理解できます。通常、我々はフロッピ−ディスクの容量は、1.44MBだと思っていますが、BIOSの仕様上は2.88MBまでサポ−トされており、2.88MBのフロッピ−ディスクであれば最近のkernelでもboot diskが作れます。よって、この2.88MBのboot diskイメ−ジを用いてフロッピ−ディスクエミュレ−ションのrescue cdromが作成可能です。

もっとも、フロッピ−ディスクエミュレ−ションには2.88MBという厳然とした制限が存在することは紛れもない事実なので、rescue cdrom作成に関し、もっぱらliloに固執する合理性はありません。今、boot disk作成の可能性にふれたのは、次項、「実験環境の構築」において、boot diskイメ−ジを用い簡便な起動実験を行うためです。


3. 実験環境の構築 qemuのインストール

再起動を繰り返す必要のある実験には仮想マシンを使用するのが合理的です。ここ では、qemuを試してみます。各ディストリビューションにrpm等が用意されている場合はそれを利用するのが良いでしょう。ここでは、とくにリビルドする意味はありません。

qemu http://fabrice.bellard.free.fr/qemu/

qemu-0.7.2.tar.gzをrpm/SOURCEにコピーし、qemu.specをrpm/SPECにコピーしてください。そしてビルドします。

$ rpmbuild -ba rpm/SPEC/qemu.spec

できあがったら、rootになってインストールします。

$ su
# rpm -Uvh rpm/RPM/i386/qemu-0.7.2.i386.rpm

起動実験は、仮想マシンqemuの仮想フロッピーディスクから起動させます。フロッピーディスクイメージの作成は少々面倒なので、スクリプトを用 意しました。ここでの実験では、とりあえずliloが起動しさえすればいいのでシステムが正しくbootするかどうかは考慮していません。以下の実験では ル−トファイルシステムが存在しないので、kernel panicで停止しますが、それが正常な動作です。
mkbd.sh

# ./mkbd.sh -e -k /boot/vmlinuz-2.4.31-0vl3

-eが2.88MBであることを示し、-k でkernelを指定します。ファイルは絶対パスで指定してください。実行にはroot権限が必要です。また、1.44MBのブートディスクイメージを作 りたいときは、-eではなく-Hを指定してください。-eまたは-Hが指定されないときは/dev/fd0の実デバイス上でliloを実行するので、作成 されたブートイメージ自体にはliloはインストールされません。

このスクリプトを実行すると、まずフロッピーを用意するように促されますが、ここではフロッピーには書き込まないので無視して、なにも入力せずEnterを押して下さい。

フロッピーディスクイメージが出来上がるとそれをフロッピーに書き込むかどうか聞いてきますので、なにか入力してEnterを押して下さい。そこで作業終 了になります。できあがったイメージは、bd.xxxx.imgというファイル名で保存されます。ちなみに何も入力せずにEnterを押すと出来上がった イメージをフロッピーディスクに書き込みます。

mkbd.shは以下のようなメッセージを出して終了します。これにより作成されたブートディスクイメージがbd.30320.imgであることがわかります。

boot disk image is bd.30320.img.
aborted.

そして、できあがったブートディスクイメージでqemuを起動します。

# qemu -fda bd.30320.img -boot a

-boot a は、-fda、つまり最初のフロッピ−ディスクイメ−ジからbootすることを意味します。

liloの起動画面が表示され、kernelがロ−ドされた後、kernel panicで停止すれば正常です。


ちなみにliloの起動時に画像を使う方法
liloの起動画像変更について

このページの実験で、/dev/hdaを/としてmountする ことがしばしばありますが、これに違和感をおぼえる人もいることでしょう。これはパーティション情報を持たないループバックデバイスによって作成されたイ メージだからですが、逆に言うとハードディスクからddなどで吹い出したパーティション情報を持つハードディスクイメージは、ループバックデバイスを使っ てmountすることができません。このようなイメージもqemuの仮想ハードディスクとすることで普通に扱えるようになります。


4. initrdの作成

第一項で言及したようにここで作成するrescue cdromは、initrdの段階でram disk上にル−トファイルシステムを展開します。おそらくこのinitrdの作成がこのペ−ジでもっとも難しい作業でしょう。なぜなら、使用する kernelは各々のユ−ザによって異なることは自明であり、kernelの初期設定を行うinitrdの動作を一般化することが非常に困難だからです。単純に は、cdromのmountが個別の環境に大きく依存するのがその最大の原因です。cdromをmountするために必要なmoduleは各々のkernel毎に違うことでしょうし、cdromのデバイス名も各環境ごとに一律ではありえません。

実際の流れを見てみます。BIOSがkernelに制御を渡した後、kernelはinitrdをram diskに展開し、それをル−トファイルシステムとして/linuxrcを実行します。ここで使用するlinuxrcは以下のようなsashスクリプトです。

#!/sash -f
/insmod isofs.o
/insmod nls_iso8859-1.o
-mount -r -t iso9660 /dev/hdc /mnt
-gunzip /mnt/root.img.gz -o /dev/ram3
-umount /mnt
exit
※sashにはスクリプトの実行に関し、versionによる互換性の問題 があります。上記は、3.7を想定したものですが、3.4では、-fオプションは不要です。unknown optionになります。逆に3.7では、-fオプションがないとスクリプトを実行できません。3.4では一行目を"#!/sash"としてください。

ここで使われているkernelは、2.4.31-0vl3で、isofs.o、nls_iso8859-1.oがmodule化されているので、単に bootした状態では、cdromをmountすることができません。よって、insmodにより、isofs.o、nls_iso8859-1.oをロ −ドし、これでcdromがmount可能になっています。もし、scsiの cdromを使いたい場合は、scsiのcdromを使用可能にする各種moduleを読み込ませる必要があります。cdromがmount可能になった ら、適切な場所にmountし、そのディレクトリ以下にあるはずのル−トファイルシステムをram diskに展開します。上記の例では、/dev/hdcを/mntにmountし、その直下にあるル−トファイルシステムの圧縮イメ−ジ /mnt/root.img.gzを/dev/ram3に伸長、書き込んでいます。これで、rescue systemのル−トファイルシステムが完成しました。後は、後片付けでumountし、exitします。

さて、このスクリプトはsashによって実行されています。sashはシステム制御系のコマンドをスタティックに内蔵した特殊なシェルで、rescue systemなどに良く使われるものです。大概のディストリビュ−ションにはrpmなりが用意されていると思いますのでインスト−ルしておいてください。

sash -- http://www.pcug.org.au/~dbell/
sash.spec

実際にinitrdの作成に必要なものを列記すると、まず、スクリプトを実行するためのsash、mountのためのmoduleおよびデバイスファイルと mount pointのためのディレクトリ、moduleをロ−ドするためのinsmod、となります。基本的に共有libraryは使わないのでinsmodはスタ ティックなものを用います。例えばVineの場合には、insmodとinsmod.staticが用意されていますので、insmod.staticを 用います。

必要なものの目途がたったならば、そのすべてが入る容量の空ファイルを用意します。

drwxr-xr-x  2 root root   1024 11月 20  2004 dev/
-rwxr-xr-x  1 root root 171303 11月 23  2004 insmod*
-rw-r--r--  1 root root  31098  9月 22 08:46 isofs.o
-rwxr-xr-x  1 root root    140  2月 13  2005 linuxrc*
drwxr-xr-x  2 root root   1024  6月 27  2002 mnt/
-rw-r--r--  1 root root   4096  9月 22 08:48 nls_iso8859-1.o
-rwxr-xr-x  1 root root 527032 11月 23  2004 sash*


この場合は、800KBもあれば良さそうです。よって、
# dd if=/dev/zero of=initrd.img bs=1024 count=800

として、空ファイルinitrd.imgを作ります。これをル−トファイルシステムとして使用できるようにファイルシステムを作ります。
# /sbin/mke2fs -m 0 initrd.img

実行すると、"initrd.img is not a block special device."と警告されますが、かまわず実行して下さい。終わったら、このinitrd.imgをル−プバックでmountし、その中にinitrd のル−トファイルシステムを構築していきます。
# mount initrd.img mnt -o loop

必要なディレクトリを作成します。
# mkdir mnt/dev
# mkdir mnt/mnt

linuxrcをコピ−し、実行権限を付与します。
# cp linuxrc mnt/
# chmod 755 mnt/linuxrc

sash、insmod.staticをコピ−します。
# cp /sbin/sash mnt/
# cp /sbin/insmod.static mnt/insmod

cdromのmountに必要なmoduleをコピ−します。
# cp /lib/modules/2.4.31-0vl3/kernel/fs/isofs/isofs.o mnt/
# cp /lib/modules/2.4.31-0vl3/kernel/fs/nls/nls_iso8859-1.o mnt/

必要なデバイスファイルをコピ−します。先述したようにcdromは環境に依存しますので、その環境に合ったデバイスを選択する必要があります。
# cp -a /dev/hdc mnt/dev/
# cp -a /dev/ram* mnt/dev/
# cp -a /dev/null mnt/dev/
# cp -a /dev/console mnt/dev/
# cp -a /dev/systty mnt/dev/
# cp -a /dev/tty[1-4] mnt/dev/
# cp -a /dev/fd0 mnt/dev/

終わったらumountし、initrd.imgを圧縮してinitrd.img.gzの完成です。
# umount mnt
# gzip initrd.img

このinitrdが正しく作成されているかを、qemuで実験してみます。前項で使用したboot disk作成スクリプトを使ってこのinitrdを用いたboot diskを作成します。-iでinitrdを指定します。
# ./mkbd.sh -e -k /boot/vmlinuz-2.4.31-0vl3 -i /root/initrd.img.gz

出来上がったら、そのboot diskイメージでqemuを実行してみます。
# qemu -fda bd.24900.img -boot a

cdromにはまだなにも指定されていないので当然ルートファイルシステムは作られず、kernel panicで停止しますが、RAMDISKが展開され、mountが失敗し、/mnt/root.img.gzがないと表示されれば、initrdは正し く実行されています。

RAMDISK: Compressed image found at block 0
Freeing initrd memory: 351k freed
VFS: Mounted root (ext2 filesystem).
mount failed: No medium found
/mnt/root.img.gz: No such file or directory
/mnt: Invalid argument
〜略〜
Kernel panic: VFS: Unable to mount root fs on 01:03


5. ルートファイルシステムの作成

前項では、initrdの作成がこのページにおいて最も難しい作業であると書きましたが、厳密な難易度は、もちろんルートファイルシステムの方が質も量も 上回ります。ただし、ルートファイルシステムの場合は環境差を考慮しなくてもよいので(環境差はkernelが吸収するので)、一般化が容易です。とは言 え、このページの主題を考えれば、ディストリビューションの作成にも匹敵するルートファイルシステムの作成にあまり深く関わるわけにもいかないので、簡便にルートファイルシステムを作り出すスクリプトを用意しました。mkrd.sh

このスクリプトは、実行した環境から必要なすべてをコピーしてきて、新たなルートファイルシステムを作成します。このルートファイルシステムは、単純には実行した環境の縮小コピーと言えます。デフォルトの構成はrescue system、ルーターとしての最低限 の機能が考慮されています。デフォルトのコマンド群 は以下の通りですが、オプションで指定して追加、削除することも可能です。

bash cat chmod cp df ed chroot ftp ifconfig insmod kill ln ls lsmod mkdir mknod modprobe mount ping ps rm mv rmmod route swapon swapoff sync umount in.telnetd mingetty login passwd chown init inetd tcpd su pidof halt lilo less rmdir telnet du w3m fdisk dd e2fsck mke2fs gzip tar grep expr iptables syslogd badblocks find touch dmesg date hdparm hwclock lspci klogd nslookup

実行にはroot権限が必要です。
# chmod 755 mkrd.sh
# ./mkrd.sh -I

以下、ルートファイルシステムが完成するとイメージとは別途にこのツリーを保存するか聞いてきますので、保存する場合は、Sを入力してください。S以外を入力す ると保存せずにルートファイルシステムイメージのみの作業を続行します。ルートファイルシステムイメージが完成したところで再度停止し、フロッピーに書き込むか聞いてきますので、なにか入力し て終了してください。ルートファイルシステムのイメージは、rd_root.xxxx.img.gzのような名前がつけられています。

ルートディスクイメージの作成が完了しました。
rd_root.4231.img.gzの大きさは5567523Bです。
rd_root.4231.img.gzは1474560Bより大きいです。おそらく、ddは失敗するでしょう。

上記のように表示されて終了します。

ルートファイルシステムが完成したら、qemuで起動してみます。
# gunzip rd_root.4231.img.gz
# qemu -fda bd.xxx.img -hda rd_root.4231.img -boot a

起動時、liloのメニューから/dev/hdaを選択してください。不具合がなければ、login画面が表示されます。

mkrd-0.1.8a for iso.img (nemu)
Linux 2.4.31-0vl3 on an i686

Created by
tampopo.karing.jp
Sun Sep 25 10:19:21 JST 2005

################ CAUTION ################
Root password is not changed from default.
Change passwords immediately!

root password is "testroot".
user1 password is "testuser1".

localhost login:


コマンドの追加は、-caオプションで行います。追加するコマンドは、絶対パスで指定し、複数のコマンドを指定するときは引用符でかこってください。
#mkrd.sh -I -ca "/usr/bin/growisofs /usr/bin/mkisofs"

デフォルトのコマンド群から削除するときは、-cdオプションで行います。削除するコマンドはコマンド名で指定し、複数のコマンドを指定するときは引用符でかこってください。現在のコマンド群は、-lcオプションで表示されます。
#mkrd.sh -I -cd "w3m in.telnetd"
#mkrd.sh -I -lc

コマンドの追加に関しては、ライブラリの依存関係を自動的に判別、解消するのでライブラリの依存関係を気にする必要はありません。ただし、このスクリプト の依存関係解消ルーチンはlddを利用しており、lddからは見えない依存関係がコマンドの完全な実行を阻害する場合があります。

デフォルトのルートファイルシステムの容量は64MBです。つまり64MBのram diskを使います。デフォルトにおいてqemuは、仮想マシンのために128MBを確保しますが、まれに128MBでは不足するときがありますので、メ モリアロケーションに関するエラーが出る場合は-mオプションで仮想マシンに割り当てるメモリを増やしてください。単位はMBです。

# qemu -m 192 -fda bd.xxx.img -hda rd_root.xxxx.img -boot a


さて、ここで作ったルートファイルシステムは素のままですので、設定ファイルその他をカスタマイズしたいと思うはずですが、これは第七項に譲ります。


極限のルートファイルシステム

さきに作成したルートファイルシステムはルータの機能を持たせているためセキュリティ重視で簡易なinitプロセスを備えていますが、より低レベルな理解を促す教材としては多少わかりにくいかもしれません。

Linuxの起動プロセスでは、boot したkernelがルートファイルシステムをmount後、initを実行します。このinitからディストリビューションの管理下に移ると言えます。通 常initは、各システムサービスを起動し、login環境を整備しますが、これらはシステムの利便性を確保するためのものであって、必須ではありませ ん。

かりにinit(/sbin/init)が存在しない場合、kernelはinitのかわりにシェル(/bin/sh)を探して実行します。単純化すると、最低限のLinuxシス テムは、initもしくはシェルとその他のファイルにより構成されます。なにをもって最低限と定義するかは難しいところですが、ファイルの読み書きなど一連のファイル操作を最低 限の条件にすると、最小、以下の3ファイルによって、それが可能なLinuxシステムが構成できます。/bin/shの実体はsashです。

/bin/sh,/dev/console,/dev/hda

実際にそのルートファイルシステムのイメージを作ってみます。
# dd if=/dev/zero of=root.sash bs=1024 count=1024
# mke2fs root.sash
# mount root.sash mnt -o loop
# mkdir mnt/bin
# mkdir mnt/dev
# cp -a /dev/console mnt/dev
# cp -a /dev/hda mnt/dev
# cp /sbin/sash mnt/bin/sh

/dev/hdaは、ルートファイルシステムが存在する任意のデバイスですが、ここでは、qemu上の/dev/hdaを用いるのでそうなっています。
# qemu -fda bd.xxx.img -hda root.sash -boot a

起動時、/dev/hdaを選択すると、ルートファイルシステムが/dev/hdaでbootします。しばらくすると、
Stand-alone shell (version 3.7)
>

とシェルが実行され制御可能になります。sashの使い方は
> help

で表示されます。Shift+PageUp、Shift+PageDownでスクロールが可能です。
さて、実は、この時点では/がreadonlyでmountされているため書き込みができません。ですので、書き込みを可能にするためremountします。
> -mount -m /dev/hda /

書き込みを実現するには、remountのためにどうしても/dev/hdaが必要なのですが、/がreadonlyでかまわないなら、最小のLinuxシステムは、/bin/shと/dev/consoleで構成できることになります。


6. rescue cdromの作成

ここまでで、rescue cdromのinitrdおよびルートファイルシステムが出来上がりました。ここでは、それらをcdromイメージにまとめ、メディアに焼き込みます。こ れまでは、2.88MBのboot diskイメージで実験を繰り返してきましたが、最終的なrescue cdromはより汎用性を優先し、boot loaderにliloではなくisolinuxを使用します。

まず、cdromイメージを作成するための作業ディレクトリを作り(iso_root)、前項で作ったルートファイルシステムのイメージファイル rd_root.xxx.img.gzをコピーします。第四項で作ったinitrdは、このファイルをgunzipすることになっているので、ここでは圧 縮されていなければなりません。
# mkdir iso_root
# cp rd_root.xxx.img.gz iso_root/root.img.gz

次にboot、isolinux関連のファイルを作業ディレクトリ(iso_root)のisolinuxディレクトリ (iso_root/isolinux)にコピーします。initrd.img.gzはinitrd.imgにコピーされています。設定ファイルとの名前 の整合性に気をつけてください。
# mkdir iso_root/isolinux
# cp /usr/lib/syslinux/isolinux.bin iso_root/isolinux/
# cp /boot/vmlinuz-2.4.31-0vl3 iso_root/isolinux/vmlinuz
# cp initrd.img.gz iso_root/isolinux/initrd.img

次に設定ファイル(isolinux/isolinux.cfg)を作成します。isolinuxの設定ファイルisolinux.cfgは、syslinux.cfgと同一の書式です。概ね直観でわか りますが、詳細は/usr/share/doc/syslinux-3.07/syslinux.docなどを参考にしてください。ここでは、各ファイルの相対パスは、このrescue cdromを/にしたときの/isolinuxがカレントディレクトリです。

以下では三種類の選択 肢が用意されていますが、これは、これまでの実験に用いたboot diskに倣ったもので最初のrescueのみでもかまいません。二番目の/dev/hda2はルートファイルシステムが/dev/hda2にあるシステ ムをbootさせる通常のboot cdromです。/dev/hda2は個別の環境に合わせる必要があります。mkbd.shで作ったデフォルトのboot diskでは実行環境のルートファイルシステムのデバイスがセットされます。三番目のrescue2は、フロッピーディスクに書き込まれた圧縮イメージを ram diskに展開し、それをルートファイルシステムとしてmountします。root=/dev/fd0となっていますが、/dev/fd0を/にmountするわけではありません。これは、boot diskでboot後、boot diskをroot diskに交換してrescue systemを作ることができる便利な方法でしたが、cdromからのノーエミュレーションbootで容量を気にすることがなくなってしまった現在はあま り意味がありません。単なるかつての名残りです。

default rescue
prompt 1
timeout 600
display boot.msg
label rescue
  kernel vmlinuz
  append root=/dev/ram3 initrd=initrd.img lang=ja devfs=nomount vga=0x311 ramdisk_size=65536
label /dev/hda2
  kernel vmlinuz
  append root=/dev/hda2 initrd=initrd.img lang=ja devfs=nomount vga=0x311 ramdisk_size=65536
label rescue2
  kernel vmlinuz
  append root=/dev/fd0 load_ramdisk=2 prompt_ramdisk=1 initrd=initrd.img lang=ja devfs=nomount vga=0x311 ramdisk_size=65536

さて、isolinux.cfg(syslinux.cfg)の書式は直観でもわかりやすい簡単なものですが、メッセージファイル(ここでは boot.msg)の書式は直観ではわかりにくいものがあります。なぜなら、boot.msgは、コンソールを直接console_codesで制御して いるからです。とりあえず、ここでは重要なコントロール文字、^Lと^Xのみ取り上げます。^Lは画面をクリアします。新しい画面にするには、一旦、すべ てを消去してから書き込まないとコンソールに残像が残ります。^Xは画像ファイルを吐き出します。^Xboot.lss<newline>で 画像ファイルboot.lssがコンソール上に表示されます。

bootに関してはboot.msgも画像ファイルも直接影響を与えないのでなくても致命的問題にはなりませんが、とりあえず以下のような感じで す。^L、^Xはコントロール文字です。ASCIIでこのまま書いても無効ですので注意して下さい。コントロール文字の詳細については、 /usr/share/doc/syslinux-3.07/syslinux.docの++++ DISPLAY FILE FORMAT ++++を参照して下さい。

^L
^Xboot.lss
 o  To boot rescue system from cdrom,
    press the <ENTER> key.

 o  To boot the system on /dev/hda2,
    type: /dev/hda2 <ENTER>.

 o  To boot rescue2 system on root disk.
    type: rescue2 <ENTER>.

syslinuxの起動時に画像を使わないときは^Xの行は不要です。画像を大きく扱いたいときは、テキストメッセージの消費行を減らしてやります。テキストメッセージは、要は見栄えだけの問題ですのでお好きなように。

^L
^Xboot.lss
press the <ENTER>:: root on /dev/hda2 type: /dev/hda2 <ENTER>:: rescue2 type: rescue2 <ENTER>


syslinux起動画像作成法
syslinuxの起動画像は、width640、16色です。heightに関しては画面自体は480ですが、画像の下にtextやpromptの表示 部が必要なのでその分をせばめなければなりません。必要なheightが480以上になると、promptが最下段に来るように単にスクロールします。起動画像に関しては、メニューやプログ レスバーを画像の上に表示し、128色使えるliloの方に優位性があるようです。


syslinuxが使用する画像形式はlssで、ppmtolss16を使ってppmからlssへ変換します。この画像のインデックスカラー16色の うち、textのカラーはインデックスナンバーの7、バックグランドカラーはインデックスナンバーの6が 使われます。もっと柔軟な設定も可能ですが、基本的にsyslinuxのconsole表示はコントロール文字で行わ れているのでわかりやすくはありません。詳細な設定は、/usr/share/doc/syslinux-3.07/syslinux.docの++++ DISPLAY FILE FORMAT ++++を参照して下さい。

というわけで、まず、GIMPなどで使用したい画像を適当なサイズにリサイズし、16色インデックスカラーに 減色、ppm画像で保存します。このファイルをboot.ppmとすると

$ ppmtolss16 <boot.ppm >boot.lss

として起動画像boot.lssの完成です。

各設定ファイル、isolinux.cfg、boot message、起動画像が出来上がったら、それらをコピーします。
# cp isolnux.cfg iso_root/isolinux/
# cp boot.msg iso_root/isolinux/
# cp boot.lss iso_root/isolinux/

これでそろいました。後はiso9660のイメージにまとめます。isolinux/boot.catはmkisofsが作るものなので、こちら で用意する必要はありません。isolinux/isolinux.bin、isolinux/boot.catはiso_root/からの相対パスで す。-J、-rはそれぞれJoliet拡張、Rock Ridge拡張です。この指定をしないとファイル名がいわゆるDOS形式になってしまうので、設定ファイルと実際のファイル名との整合性が壊れる場合があ ります。その他のオプションはboot cdromを作るためのものです。

# mkisofs -J -r -o rescue.iso -b isolinux/isolinux.bin -c isolinux/boot.cat \
                -no-emul-boot -boot-load-size 4 -boot-info-table iso_root/

rescue.isoが出来たら、例のごとくqemuで起動してみます。cdromからのbootなので-bootにはdを指定しています。
# qemu -cdrom rescue.iso -boot d

loginまで辿り着ければイメージは完成です。後はCD-Rに焼き付けます。ルートファイルシステムの設定変更、カスタマイズに関しては次項でふれます ので、設定の変更、カスタマイズが必要な場合は、設定の変更、カスタマイズを施したルートファイルシステムイメージで置き換え、再度mkisofsでまと め直し、焼き込んで下さい。

# cdrecord -v dev=0,4,0 speed=6 rescue.iso

出来上がったら、そのCD-Rでもう一度qemuを実行してみます。
# qemu -cdrom /dev/cdrom -boot d

loginまで辿り着ければ、rescue cdromの完成です。


7. 起動実験、設定の変更、カスタマイズ

第六項においてloginまでたどりつきました。ここでは最終目標であるrescue systemとホストマシンのネットワーク構築を試みます。

これまで、簡便のためほとんどの作業をroot権限で実行してきましたが、 中にはroot権限の不要なものも多々あります。また、qemuの実行に関し、root権限で作成した各イメージは、そのままでは一般ユーザが利用できな い場合もあるので、実際の運用では、適宜、適切なパーミッションが必要です。具体的には、boot diskに用いてきたboot diskイメージは書き込み権限がないとbootできません。ハードディスクイメージの場合は書き込み権限がなくても一見正常に動作しているように見えま すが、qemu上で書き込み操作が正常に行われたように見えても実際には書き込まれないので、やはり書き込み権限が必要です。

さて、仮想マシン上ではネットワークのみならず多くのデバイスに関し完全に通常 のマシンと同様に操作すれば良いのですが、ホストマシン側は仮想マシンを通常のマシンとみなして扱う設定が必要です。具体的には、qemuの接続先である ホストマシンのネットワークノードをqemuの起動時に設定しておかなくてはなりません。デフォルトでは、qemuが/etc/qemu-ifupを起動 時に実行してホストマシンのtunドライバ(ネットワークデバイス)を有効にします。このスクリプトはqemuが起動時に自動実行するものなのでユーザはスクリプ トを用意するだけです。

この/etc/qemu-ifupは以下のような極めて単純なスクリプトで、現在使われていないネットワークデバイスtun?を$1に指定してネットワークインターフェイスを有効化します。

#!/bin/sh
sudo /sbin/ifconfig $1 192.168.99.7

ネットワークの設定などは当然root権限が必要なので、sudoなどで適切に処理しないと一般ユーザでは利用できなくなってしまいます。また、tun? は/dev/net/tunというデバイスファイルとしての実体がありますので、このパーミッションも正しく設定しないと一般ユーザではqemuのネットワークを利用できないという 事態に陥ります。

一応、これでホスト側の設定は済みました。ここでは、tun?に192.168.99.7が割り当てられています。qemuの仮想ハード的には、そこに eth0で繋がれているので、qemu上のeth0に192.168.99.7と同一セグメントのIPアドレスを与えれば通信が可能になります。

qemuのeth0は、ne2k-pciです。当然、ネットワークで繋ぐにはこのインターフェイスを有効にせねばなりません。しかし、第五項で作ったルー トファイルシステムにはkernel関係のものは入っていません。これは、ルートファイルシステムの作成に際し、どのkernelが使用されるのかを予測 することは不可能だからです。というわけで、ne2k-pci.oおよび依存するmoduleをrescue cdrom中に入れなくてはなりません。とにかくネットワークさえ使えるようになれば後はいくらでもやりようがあるので、ネットワークの設定を最優先します。

圧縮されている場合は伸長し
# gunzip rd_root.xxx.img.gz

ループバックでmount後、必要なmoduleをコピーしてやります。
# mount rd_root.xxx.img mnt -o loop
# cp -a /lib/modules/2.4.31-0vl3 mnt/lib/modules

終わったら、umountし、そのrd_root.xxx.imgでqemuを起動します。
# qemu -fda bd.xxx.img -hda rd_root.xxx.img -boot a

liloが起動したら、メニューから/dev/hdaを選択してbootさせます。login画面にパスワードが書いてあるので、それでloginしてく ださい。loginしたらパスワード変更をお忘れなく。この後は、まったく通常の設定を行っていきます。この項ではネットワークが優先なので、以下を実行 し、
# modprobe ne2k-pci
# ifconfig eth0 192.168.99.100
# ping -c 3 192.168.99.7

pingが通れば終了です。これから、ネットワーク、ルーティング等々、柔軟で難解な様々な設定が楽しめます。とりあえず、デフォルトゲートウェイを設 定、DNSを参照できるようにし、w3mでネットに繋げてみて下さい。また、デフォルトではtelnetdが起動していますので、ホストマシンから loginしてみてください(この場合、ホストマシンがルータの役目をすることになりますが、当然、ホストマシン側のネットワークも適切な設定が必要です)。設定の変更、カスタマイズが完了したら、 shutdownし、qemuを終了します。これで設定の変更、カスタマイズが反映したルートファイルシステムrd_root.xxx.imgが出来上が ります。

日本語キーボードへの対応
qemuの仮想キーボードはホストマシンのキーボードとは無関係で、デフォルトは、us配列です。これを日本語配列のキーボードにするには、-k ja で起動します。

# qemu -k ja -fda bd.xxx.img -hda rd_root.xxx.img -boot a

起動後、qemu上でloadkeysを実行して下さい。

#loadkeys jp106

これで、日本語キーボードが正しく使えるようになります。この設定を起動時に反映させるには/etc/sysconfig/keyboard


KEYTABLE=jp106

と書いておくか、rc.localに直接、
loadkeys jp106を書くかします。


ここで作ったrescue systemはram diskを念頭に作られているので、rescue system上で行った設定の変更やカスタマイズは保存されません。rescue cdromの設定変更やカスタマイズを実行したい場合は、上記のようにイメージファイルそのものをルートファイルシステムとしてqemuを起動し、その仮想 環境で設定変更、カスタマイズを行い、そのルートファイルシステムのイメージでrescue cdromを焼く必要があります。


8. まとめ

initrdの作成は環境に大きく依存すると先述しましたが、個別の環境に動的対応するシステムも構築可能です。旧来のフロッピーディスクという 限られた環境では実現しにくかったのですが、cdromの容量まで拡張されれば余裕でしょう。インストーラなどがわかりやすい実例です。とは言え、デバイ スの自動判別等はこのページの主題とは異なるでしょうし、boot diskによる簡便な実験にも少なくない意味があったと思っています。

ここで作ったrescue cdrom、もっと厳密にはここで作ったルートファイルシステムは単なる雛型にすぎません。自分の求めるカスタマイズを求めて試行錯誤することこそ、このページの真の最終目標です。

とにもかくにも、rescue systemの構築は、Linuxシステムのゼロからの構築を意味し、なかなかやりごたえのあるテーマです。低級な問題から高級な問題まで幅も広く奥も深 いです。初心者の方にはなかなかハードルが高いと思われますが、我と思う中級者の方には果敢に挑んでもらいたいと思います。


2005-09-25 よしのぶ 
yoshino@rita.karing.jp 

 index.html 飛べ!ペンギン大王