1FD FreeBSDの世界
遠い昔に自分のwebサイトで公開していたデータが出てきたので、半ば保存目的でnoteにコピーしておきます。
1FD FreeBSDとは
1FD FreeBSDとは、フロッピーディスク1枚で起動するFreeBSDシステムのことです。たった1474560バイトの中に、いかにしてマトモに動作するFreeBSDシステムを詰め込むかという試みです。
しかし、最近は大容量のハードディスクが安価に手に入る時代です。フロッピー1枚に、FreeBSDと、例えばSambaやApacheを詰め込んでサーバにする、という手段もありますが、バージョンアップ時の面倒さや、フロッピーディスクの信頼性、その他を考えると、大容量のハードディスクに普通にシステムを構築した方が結局は楽、という結論になってしまいます。
よって、googleでネット上を検索してみても、趣味人が1FD Router等を古い(2.x系、3.x系、せいぜい4.7辺りの)バージョンのFreeBSD(やLinuxとか)を使って構築した、という記録が見つかる程度でした。
1FD FreeBSDの本領発揮!
そろそろ時代錯誤的となってしまった1FD FreeBSDの世界。コレが本領発揮する用途を考えてみました。
1FD ハードディスクデュプリケータ
1FD ハードディスク完全消去ユーティリティ
以下、これらのシステムの構築方法と使い方を解説したいと思います。また、ダウンロードしてフロッピーなりCDROMに焼きこめばそのまま使えるイメージも用意しましたので、興味のある方は試してみてください。(注:この部分は原文ママなので、イメージは存在しません)
1FD FreeBSD カーネル構築編
1FD FreeBSDに必要なユーティリティを詰め込む前に、まずはOS自体の構築方法について解説します。
必要なもの
FreeBSDが動作するパソコン一台
フロッピードライブ
マトモなフロッピーメディア(CDRメディアに、フロッピーのブートイメージとして焼いちゃっても良いかもしれません。)
まずは普通にFreeBSDのインストール
1FD FreeBSDを作るには、まず普通に(ハードディスクに)インストールしたシステムが必要になります。
このFreeBSD上で、フロッピーに収まるカーネルを構築したり、crunchされたshをはじめ各種ツールのバイナリを作成するわけです。 FreeBSD5.x以降は、カーネル周りのディレクトリレイアウトが変わったため、1FDに収めるためにどうしたら良いか良く分からんので(おい)、FreeBSD4.11-Releaseをベースにしました。
これを書いている現在(2006年9月)、4.11Rは少々古い感じはするものの、obsolereされている訳でもないし、安定性や対応ハードウェアの面においても不自由は無いので、問題は無いでしょう。
(2006/10追記:FreeBSD6.1Releaseで試してみましたが、機能を削りまくったカーネルを作成しても、圧縮後のサイズが1.5MB程になってしまったため、やはり4.11で作るのが現時点では最良のようです)
FreeBSDのインストール方法
普通にインストールすれば良いです。ソースファイルは全て展開しておいた方が良いでしょう。(ま、kernelのソースと、bin,sbin,ubin,usbin辺りだけあれば良い筈ですが)
FreeBSDのインストール方法については省略します。
1FD FreeBSD用カーネルの構築
この辺からが本番です。
FreeBSDのインストールはした事があっても、カーネルの再構築は経験が無い人も居ると思いますので、ちょっと丁寧に書いてみます。
カーネルの設定ファイルは、/usr/src/sys/i386/conf/ にあります。GENERICってのがデフォルトの設定ファイルです。
このGENERICを元にして、1FD FreeBSD用のカーネルコンフィグファイルを作成します。
1FD FreeBSDには、NFSで何かをマウントする予定があるならともかく、普通はNFSは不要だと思います。また、SCSI関係やCDROM関係も要らないと思います。ISA NIC関係は要らないと思いますが、PCIなNICに関しては、稼動開始後にNICが壊れて入れ替えたりとか、あるいは1FD ディスクデュプリケータのように、稼動させるシステムが決め打ち出来ない場合を考え、全て残しておきました。
この辺は各人の状況に合わせて設定してください。参考までに、私のコンフィグを書いておきます。
さて、コンフィグが出来たらカーネルの構築です。
make installしてしまうと、今稼動しているシステムのカーネルを置き換えてしまうので注意してください。もし万が一make installしてkernelが書き換わってしまった場合は、
で元に戻ります。kernelは大変重要なファイルなので、誤って消去できないよう、削除不可フラグが立っています。何かしらの事情で消去なりする必要が生じた場合は、chflagsでフラグを変更してから操作します。
以上の操作で、新しいカーネルが /usr/src/sys/compile/1FD_FreeBSD/kernel に出来ました。
次は、crunchされた各種プログラムを作成します。
Crunched Binary作成編
Crunched Binaryとは
1FD FreeBSDのカーネルを作成したら、次はcrunchされたバイナリを作成します。crunched binaryとは、引数の取り方によって挙動を変える、実体としては単一のバイナリファイルです。
例えば、"prog"という単一のバイナリに、cat,ls,cd,dd,pingという複数の機能を持たせて、
…と言った具合です。たくさんの機能を詰め込めばそれだけサイズは大きくなりますが、コマンドを厳選してやれば、十分にフロッピー1枚に詰め込むことができます。
それでは、crunched binaryの作り方を説明します。
必要なコマンドを挙げる
まず最初に、どのコマンドを詰め込むか取捨選択します。とりあえず私が選んだものは以下の通りです。
ここまでが、FreeBSDのシステムで標準で用意されているコマンドです。
この二つは、ネットワーク経由でのHDイメージ送出・受取に用います。
tcpserverは、DJBのucspi-tcpに入っているものを使いました。入手元は、
です。DJBは好き嫌いが分かれるとは思いますが(笑)。
システムに標準で用意されていない外部プログラムをcrunched binaryに取り込むテクニックはこの後で示します。
作業ディレクトリの作成
どのコマンドを取り込むかを決めたら、作業ディレクトリを作ります。私は、/root/fd/ に1FD FreeBSD作業用ディレクトリを作ったので、更にその下にcrunchディレクトリを作成し、そこで作業することにしました。フルパスは/root/fd/crunch/ になります。
実行バイナリ名の決定
crunche binaryの名前を決めます。これは別に何でもいいのですが、私は"execimg"にしてみました。
crunchgen設定ファイルの作成
いよいよ、crunched binaryの作成に入ります。まずは設定ファイルを作ります。
私は"execimg"というバイナリ名にしたので、/root/fd/crunch/execimg.conf という設定ファイルになります。
このファイルの内容は以下の通りです。
この内容で設定ファイルを保存しました。
さて、この段階で早速crunchgenを実行すると、
と言われてしまいます。
要するに、標準でシステム内に用意されているプログラム以外は、ソースファイルのある場所が分からん!と言われてるわけです。
そこで、まずはそのソースディレクトリを用意します。
tcpclientとtcpserverの展開、コンパイル、ソースディレクトリの準備
ucspi-tcp-0.88.tar.gzを、/tmpで展開しました。
すると、/tmp/ucspi-tcp-0.88/ にソースが展開されます。ここに移動してmake。
これでオブジェクトが作成されます。次に、crunchgenの要求により、コマンド名に対応するディレクトリを作成し、そこに必要なファイルをコピーしてやります。
これでやっとcrunchgenが通・・・りません。試しにやってみると、
と言われるはずです。
FreeBSD日本語マニュアルによると、
とあります。そこで、tcpclientとtcpserver用に、それぞれのディレクトリのMakefileを書き換えます。
/root/fd/tcpclient にあるMakefileは、
と書き換えます。同様に、/root/tcpserver/Makefile は、
と書き換えました。これで、crunchgenを実行してみます。
エラーが出なければOKです。さて、この段階でmakeを実行しても、まだエラーとなるはずです。
原因は、execimg.mkの中で、tcpserverとtcpclientの部分で、"make depend;make~"の部分に対応するMakefileの記述が、それぞれのビルドディレクトリにあるMakefileに記述されていないためです。
しかし、tcpserverやtcpclientを作成するのに必要なオブジェクトファイルは既にあるので、execimg.mkの該当部分を単に削除してやるだけでmakeが通るはずです。
(この辺の実機の記述を記録し忘れたため、後日追ってこの部分記述する予定)
エラーが出なければ、無事crunched binary作成完了です。
エラーが出る場合のチェックポイントは、
execimg.confの中で、必要とするライブラリの列挙に漏れが無いか
システム標準で用意されているツール以外のものを取り込んだ場合、Makefileが要求仕様通りか
といった辺りをチェックしてみてください。
Makefileを書き換えたりと、少々敷居が高いですが、この方法で実際に問題なくコンパイルできていますので、大丈夫だと思います。
カーネル、クランチバイナリが作成できれば、次はいよいよフロッピーの作成です。
1FDディスクイメージ作成
わざわざ1FDイメージファイルを作成する理由
1FD用のカーネルを作成し、shをはじめとしたcrunchされたツールを準備したら、次は1FDのディスクイメージの作成です。
これは何故かと言うと、実体としてのフロッピーディスク上には、圧縮されたカーネルと1FDのイメージを用意し、ブートローダからカーネルをメモリに展開、そして圧縮された1FDのイメージをメモリ上に展開し、そのイメージをマウントして動作させるという動きになるからです。
勿論、カーネルやツールを圧縮することなく1FDに収められればそんな面倒なことは必要ないのですが、機能を削ったカーネルだけでも1.8MBほどあるため、こういった面倒な手法を使わざるを得ないのです。
さて、メモリ上に展開する1FDのイメージを作成します。
これでひとまず1.44MBの空のファイルが出来ました。
これで、作成したファイルを仮想的にマウントできるようになります。そして、ファイルシステムとしてマウント可能にするため、ディスクラベルを書き込みます。これは、「俺は1.44MBのフロッピーだよ?」と宣言するためのもので、これが無いと正常にマウントできないという具合。
そして、ファイルシステムを作成。
これでマウントして読み書きできるようになります。
以降、展開後のフロッピーイメージを/mntに対して構築していきます。その実体は/root/fd/mfsroot.imgにあり、作業終了後は/mntをアンマウント、そしてmfsroot.imgを圧縮してフロッピーにコピーしてやるわけです。
1FD ディスクイメージ上にディレクトリを作成
1FDイメージ上にディレクトリを作成します。
この中でfdというのは、圧縮されたFDイメージが展開された後、元の物理的なフロッピーは切り離されてしまう(マウントされない)ため、改めて物理的なフロッピーディスクをマウントし直すために作ってあります。
起動シーケンスの中で元のフロッピーディスクをマウントし、そこに記述した起動スクリプトを実行することで、設定を柔軟に変更することが出来るわけです。
(1FDイメージファイルの構成を変えるためには、一旦vnデバイスに結び付けてマウントし、マウントした上で作業して、それを再度圧縮してフロッピーに書き戻すという非常に面倒な作業になるので、1FDイメージファイルは、一旦出来上がってしまえば、あとは極力いじりたくないわけです)
それから、/binと/sbinを作成します。といっても、/に対するシンボリックリンクですが。
デバイスファイル作成
これで必要なデバイスファイルが作成されました。後はMAKEDEVは用済みなので消してしまって構いません。
crunched binaryをコピー
既に作成済みのcrunched binaryを仮想FDイメージ上にコピーします。そして、中に織り込んだコマンドの数だけ、ハードリンクを作成します。
/etc/rcを作成
1FDイメージが展開された後実行される/etc/rcを作ります。
といっても、ネットワークの設定その他は、1FDイメージからマウントした物理フロッピーの中に書くので、ここでは単に物理フロッピーのマウントを行うだけでOKです。
以下、/mnt/etc/rcの内容です。
というわけで、物理フロッピーをマウントし、そこに書いたrcを実行し、shを立ち上げるだけです。
無駄領域をゼロパッド
作成した1FDイメージを圧縮する際、圧縮率を上げるために空き領域をゼロで埋めると良いらしいのですが、実際に処理前と処理後でサイズを比較したところ、むしろ処理前の方が圧縮率が良かったりしました。多分たまたまだと思いますが、それほど劇的な効果がある訳でもなさそうです。(場合にもよるでしょうが)
ギリギリまでコマンドを詰め込んだ場合などは、空き領域をゼロパッドするよりも、一旦dumpして新しく作成したイメージにrestoreしてやると良いみたいです。私はそこまでするほど容量がカツカツでもないので、その効果がどれほどかは良く分かりません。
一応、ゼロパッドの方法は、
といった具合です。
余談ですが、Windowsのシステムディスクなどは、defragした後空き容量をゼロパッドすることにより、物理ディスクイメージファイルの圧縮後サイズが劇的に小さくなったりします。
アンマウント
最後はアンマウントして終わりです。
これで、編集作業が反映したmfsroot.imgファイルが出来上がりました。
起動フロッピーディスク作成
物理メディア作成
いよいよ、物理的な起動フロッピーディスクを準備します。ここに、ブートローダと、圧縮したカーネルと、圧縮した1FDイメージファイルを書き込んで終わりです。
下手なメディアを使うと、一見正常に見えて起動時に読み込みエラーになるとか、とかくトラブルの元になるので、絶対に信頼のおけるメーカーの新品のメディアを用意してください。
これで物理フロッピーを/mntにマウントして、bootディレクトリを作成しました。
bzip2対応ローダの作成とコピー
物理フロッピー上に/boot/loaderを作るわけですが、圧縮率向上のため、bzip2したカーネルを展開できるようにします。
loaderのソースは、/usr/src/sys/boot/i386/loader にあります。
forth無効、gzip無効、bzip2有効のloaderを作るには、
とやって作ります。ファイルが足りん!と言われてmakeが途中で終了した場合は、/usr/srcに移動し、makeを実行することにより、必要なオブジェクトファイルが作成され、今度はちゃんとloaderのコンパイルが出来るはずです。
ちなみに、手元で実験してみた結果、
デフォルトのローダ(forth・gzip有効):155648バイト
forth無効・gzip有効:114688バイト
forth無効・gzip有効・bzip2有効:135168バイト
forth無効・gzip無効・bzip2有効:114688バイト
と言った感じでした。出来上がったloaderをkgzipしてフロッピーにコピーします。
loaderは、/boot/loader.rcを読み込むので、これを作成します。
/mnt/boot/loader.rcの内容は、以下のとおり。
カーネルと1FDイメージファイルの圧縮とコピー
あとは、作成したカーネルと、メモリ上に展開される1FDイメージファイルを圧縮してフロッピーに入れるだけです。
ところで、bzip2対応のloaderを作ったわけですが、これが圧縮率の高いbz2ファイルは展開できないようです。
bzip2 -1で圧縮すれば展開できるので、これで圧縮してコピーします。
設定ファイルの作成
柔軟な設定を可能にするため、物理フロッピーディスク上に作成したrcファイルを実行する設定にしました。必要に応じて、これを設定します。
以下、/mnt/rcの設定例です。
見れば分かると思いますが、まずifconfigでインターフェースの設定をします。もし、複数のNICが刺さっていて、しかも同一のアドレス空間に接続されている場合は問題が起きますが、普通はそんなことは無いでしょうから…。
一番下の二行は、今回の1FDディスクデュプリケータのメイン部分です。
tcpserverの行は、コピー元となるマシンの場合有効にしてください。
tcpclientの行は、コピー先となるマシンの場合有効にしてください。
これを間違えると死にますので御注意を。
なお、サーバ側の同時接続数は -cオプションで設定します。とりあえず250台にしてありますので、同時に250台まで並列処理できます。もっとも、ネットワーク的/サーバのディスク読み取り速度的に、どれだけ時間が掛かるか分かりませんが…笑。
例として、コピー先マシンの設定例を挙げておきます。
IPアドレスは、コピー元と同じアドレス空間で適当に設定します。
設定後は、xビットを立てておきましょう。
後は、フロッピーをアンマウントすればおしまい。
試しに、フロッピーから起動させてみましょう。ちゃんと起動しましたか?送出元/送出先のメディアを突っ込んだ二台のPC間で、データ転送が行われましたか?くれぐれも、ディスクが消えては困るパソコンで、間違えてデータ書き込みをしないように。その辺は自己責任でどうぞ。
応用、など
今回、フロッピーから起動させた二台のPC間でのディスクコピーツールを作成しましたが、別に集中的なデータサーバを置いておき、正常起動時のディスクイメージをネットワーク経由で保存しておき、障害時にそこからデータを取得して書き戻す、なんてシステムもちょっと工夫すれば簡単に出来上がります。
「瞬快」等の専門ツールに比べれば手間も時間も掛かりますが、なんと言っても原材料費無料で作れるのが嬉しいところ。
専門学校などで、学生にLinuxなどの実習をさせる場合、学生に自由に使わせた後、予め作成しておいた標準環境に書き戻す、なんて場合が一番威力を発揮しそうな気がします(ライセンス的にも。) Windowsの場合、基本的にはこのような方法で複製を作るのはまずいですが、ディスクのスナップショットを保存する集中サーバを用意し、個別に書き戻すのであれば問題ない気がします。
復元に一晩掛かるのが欠点ですが、学校などの場合、一日の終わりや一週間の終わり等のタイミングで環境を元に戻す、なんて場合には有効かもしれません。