ROMFS - ROM ファイルシステム

ROM ファイルシステムは、主にインストールディスクセットの初期 RAM ディ
スクのためのとても簡単な読み出し専用のファイルシステムです。ブート時に
リンクされるモジュールを持つ必要から発展してきました。このファイルシス
テムを使用して、オフィスの地下に置いたルータの機能のために必要なメモリ
を消費しないで同等の機能を実現できますし、さらには小さなカーネルにでき
る可能性もあります。

比較のために、昔の minix と xiafs (後者は廃止されました) ファイルシス
テムのどちらもモジュールとしてコンパイルすると 20000 バイト以上必要で
すが、romfs では 1 ページつまり 4000 バイトも必要ありません (i586 を想
定しています)。同じ条件下で、nfsroot を伴う nfs モジュールが約 57K で
すし、msdos ファイルシステムは約 30K (しかもデバイスノードやシンボリッ
クリンクはサポートされません) です。その上、ちょっと不公平な比較になり
ますが、実際に、ext2 を用いたレスキューディスクは 3202 ブロック以上使
用し、romfs では 3079 ブロック必要でした。

このファイルシステムを作成するために、genromfs というユーザプログラム
が必要です。sunsite.unc.edu およびそのミラーサイトの
/pub/Linux/system/recovery/ ディレクトリから anonymous ftp により入手
できます。

名前が示すように、romfs は、やろうと思えば :) (E)EPROM ディスクのよう
な (領域を効果的に用いる必要のある) 様々な読み出し専用メディアに使用す
ることもできます。

しかしながら、romfs の主要な目的はこのファイルシステムだけをリンクした
とても小さなカーネルを持ち、後から現状のモジュールユーティリィティで任
意のモジュールをロードすることができるようにすることです。さらに、SCSI
デバイスや、IDE やフロッピードライブが必要かどうか決めるプログラムを実
行するために使用することもでき、その上、カーネルの "initrd" (初期 RAM
ディスク) 機能を使えば、それら(のモジュールを) 後でロードできます。実
際には目新しい話ではありませんが、romfs は必要となる ext2 や minix や
果ては affs といったファイルシステムの代わりにすることができます。

例えば、ディストリビューションのブートディスクは cd ディスクドライバ
(とたぶん SCSI ドライバ) および ISO 9660 ファイルシステムモジュールだ
けを含むことができます。他のファイルシステムを持たないので、カーネルを
十分に小さくでき、ext2fs モジュールのように本当に大きなものは、インス
トールの後の段階に CD からロードすることができます。他には、ネットワー
クからワークステーションを再インストールする時のリカバリディスクとして
使い、近くのサーバからすべてのツールやモジュールをロードするようにもで
きます。単にこのリカバリディスクが ext2 では一枚のディスクに入らないと
いう理由のみで、この目的のために二つのディスクを持ちたくないでしょう。

あなたが期待しているように、romfs はブロックデバイスを扱え、基本構造は
非常に単純です。すべてのアクセス可能な構造体はアクセスを速くするために
16 バイトの境界から始まります。ファイルが必要とする最小の領域は 32 バ
イトです (これは名前が 16 文字未満の空のファイルです)。任意の空でない
ファイルの最大のオーバヘッドは、ヘッダ、ファイル名を 16 バイトにするパ
ディング、ファイルの内容を 16 バイトにするパディングで、16+14+15=45 バ
イトになります。しかし、ほとんどのファイル名が 3 バイトより長く、15 バ
イトより短いので、これは全く稀です。

ファイルシステムのレイアウトは下記のとおりです。

オフセット    内容

        +---+---+---+---+
  0     | - | r | o | m |  \
        +---+---+---+---+       バイトでのASCII 表現
  4     | 1 | f | s | - |  /    (すなわち "-rom1fs-")
        +---+---+---+---+
  8     |   full size   |       このファイルシステムのアクセス可能なバ
        +---+---+---+---+           イト数
 12     |    checksum   |       最初の 512 バイトのチェックサム
        +---+---+---+---+
 16     | volume name   |       ゼロでターミネートされたボリューム名
        :               :           16 バイト境界までパディング
        +---+---+---+---+
 xx     |     file      |
        :    headers    :

複数バイトからなる値 (32 ビットワードのことで以下ロングワードと表現し
ます) はビッグエンディアン順を使用します。

最初の 8 バイトはファイルシステムの識別子で、たまたま覗くことになった
人のためにも置かれています。その後の三番目のロングワードはこのファイル
システムの初めからアクセス可能なバイト数を示します。四番目のロングワー
ドは最初の 512 (もしくはアクセス可能なバイト数の小さい方) バイトのチェッ
クサムです。アルゴリズムは AFFS ファイルシステムで使用しているのと同じ、
単純なロングワードの合計です (ビッグエンディアンの量と仮定しています)。
詳しくはソースを見てください。このアルゴリズムはエラー検出力は高くあり
ませんが、表を使用せず非常に単純なので選ばれました。

次に続くバイトはファイルシステムの一部です - 各ファイルヘッダは 16 バ
イトの境界で始まっています。

オフセット    内容

        +---+---+---+---+
  0     | next filehdr|X|       次のファイルヘッダのオフセット
        +---+---+---+---+         (次のファイルが無ければゼロです)
  4     |   spec.info   |       ディレクトリ／ハードリンク／デバイスの
        +---+---+---+---+           情報
  8     |     size      |       このファイルのバイト数
        +---+---+---+---+
 12     |   checksum    |       ファイル名およびそのパディングを含むメ
        +---+---+---+---+           タデータを網羅する
 16     | file name     |       ゼロでターミネートされたファイル名
        :               :           16 バイト境界までパディング
        +---+---+---+---+
 xx     | file data     |
        :               :

ファイルヘッダは常に 16 バイトの境界で始まるので、next filehdr のポイ
ンタの下 4 ビットは常にゼロです。この 4 ビットはモード情報のために使用
されます。ビット 0..2 はファイルの種別を、ビット 4 はファイルが実行可
能かどうかを示します。このビットがセットされていなければ、パーミッショ
ンはすべての人が読めるとみなし、セットされていればすべての人が実行でき
るとみなします - キャラクタおよびブロックデバイスは例外で、所有者以外
はアクセスできません。すべてのファイルの所有者のユーザ id および グルー
プ id は 0 で、これは意図した使用の範囲で問題にならないはずです。ファ
イル種別の 8 つの値は次のとおりマップされます。

          マップ                spec.info の意味
 0      hard link       リンク先のファイルヘッダ
 1      directory       最初のファイルのヘッダ
 2      regular file    未使用、0 でなければならない
 3      symbolic link   未使用、0 でなければならない (file data はリン
                        クの内容)
 4      block device    前後 16 ビットが各々メジャーおよびマイナー番号
 5      char device                 - " -
 6      socket          未使用、0 でなければならない
 7      fifo            未使用、0 でなければならない

ハードリンクはこのファイルシステムの中で特別なマークがされますが、期待
する振る舞い (すなわち、inode 番号の共有) をすることに注意してください。
さらにハードリンクのループを作らないことやディレクトリ向けに . や
.. のリンクを作ることは、あなたの責任であることに注意してください。通
常、これは genromfs プログラムによって正しく行われます。ソケットや
fifo などの特殊ファイル上で特別な目的のために実行可能 ビットを使用する
ことは止めてください。それらは今後他の目的で使用されるかもしれません。
また、レギュラーファイルとシンボリックリンクだけは、必ず size フィール
ドがゼロにならないことを覚えておいてください - それらは (パディングさ
れた) ファイル名のすぐ後に利用可能なバイト数を持っています。

他に注意することは、romfs はファイルヘッダおよびデータが 16 バイト境界
に配置されて動作しますが、ほとんどのハードウェアデバイスおよびブロック
デバイスのドライバはブロックサイズより小さなデータを処理できません。こ
の制限を克服するために、ファイルシステムの全体のサイズを 1024 バイトの
境界までパディングしなければなりません。

このファイルシステムに関する不具合や提案があれば、私に連絡してください。
しかし、このファイルシステムの本来のそしてとても重要な利点はコードが小
さいことなので、機能やコードの追加を私に希望する前に二回は熟考してくだ
さい。一方、私は romfs に関するメールをあまりもらっていないので、気軽
にメールしてください。フィードバックを得るために、Avery が ARCnet の中
で何故ポエムを書いたか、今では私も理解できます :)

romfs のメーリングリストもありますが、現在まで、流量がありません。なの
で、あなたのアイデアを議論するために、参加することを歓迎します :)

ezmlm により運営されてますので、romfs-subscribe@shadow.banki.hu にメッ
セージを送ることで参加できます。内容は無関係です。

未決の問題：

- パーミッションおよび所有者の情報は Un*x ライクなシステムにとって、か
  なり本質的な機能ですが、romfs は完全には実現していません。私はこれが
  制約となる場合を見つけたことがないのですが、問題であると考える人もい
  るかもしれません。

- このファイルシステムは読み出し専用なので、非常に小さくなりますが、誰
  かがファイルシステムに *何かを* 書きたい場合、依然として、書き込み可
  能なファイルシステムが必要になり、サイズの利点がなくなります。考えう
  る解決策 - コンパイル時のオプションで書き込みアクセスもしくは、新し
  く似たような RAM ディスク用の小さな書き込み可能なファイルシステムを
  実装してください。

- ファイルは 16 バイトの境界にアライメントを行うことだけが要求されるの
  で、ファイルシステムからファイルを読んだり実行することは、現状ではた
  ぶん最適な状態ではありません。ファイルのデータの大部分 (つまり、最初
  のものと最後のものを除く) を "自然な" 境界に置くよう整理することで解
  決するかもしれません。これは、mm サブシステムにファイルの内容の大部
  分を直接マップすることでできるでしょう。

- 圧縮は便利な機能かもしれませんが、メモリが大きな制限要因になると思わ
  れます。

- どこで使用されますか？

- intel および motorola 以外のアーキテクチャで動作しますか？


楽しんでください！
    著者：Janos Farkas <chexum@shadow.banki.hu>
日本語訳：野本浩一 <hng@ps.ksky.ne.jp>
    校正：Seiji Kanekoさん <skaneko@a2.mbn.or.jp>
