                    initramfs バッファフォーマット
                    ------------------------------

                       Al Viro, H. Peter Anvin
                        最終更新日: 2002-01-13

カーネル 2.5.x から、以前の「初期 RAM ディスク」プロトコルは、新しい
「初期 ramfs」 (initramfs) プロトコルによって置き換え/補完されつつあり
ます。initramfs の内容は、初期 RAM ディスク (initrd) プロトコルで使用
されていたのと同じメモリバッファプロトコルを使って渡されます。しかし、
その内容は異なります。initramfs バッファは ramfs ファイルシステムへと
展開されるアーカイブを含んでいます。このドキュメントでは、initramfs
バッファフォーマットの詳細について記述します。

initramfs バッファフォーマットは "newc" もしくは "crc" CPIO フォーマット
に基づいており、cpio(1) ユーティリティで作成することができます。cpio
アーカイブは gzip(1) で圧縮することができます。このため、単一の .cpio.gz
ファイルは、initramfs バッファの有効な形式の一つとなります。

initramfs バッファの完全なフォーマットは、下記の文法により定義されます:
        *         0 回もしくはそれ以上の出現を意味します
        (|)       いずれか一つを意味します
        +         結合を意味します
        GZIP()    オペランドの gzip(1) を意味します
        ALGN(n)   n バイト境界までのヌルバイトによるパディングを意味します

        initramfs := ("\0" | CPIO アーカイブ | CPIO gzip アーカイブ)*

        CPIO gzip アーカイブ := GZIP(CPIO アーカイブ)

        CPIO アーカイブ := CPIO ファイル* + (無し | CPIO トレイラ)

        CPIO ファイル := ALGN(4) + CPIO ヘッダ + ファイル名 + "\0" + ALGN(4) + データ

        CPIO トレイラ := ALGN(4) + CPIO ヘッダ + "TRAILER!!!\0" + ALGN(4)


分かりやすく言うと、initramfs バッファは、圧縮された、もしくは圧縮されて
いない ("newc" もしくは "crc" フォーマットの) CPIO アーカイブの集合です。
任意の個数のゼロバイトを (パディングのために) 各メンバ間に置くことができます。

cpio の "TRAILER!!!" エントリ (cpio アーカイブ終端) は任意ですが、無視は
されません。下記の「ハードリンクの扱い」を参照してください。

CPIO ヘッダの構造は下記のとおりです (全てのフィールドは、16 進数の ASCII
数字で、フィールド幅全体を埋めるように左側に '0' がパディングされます。
例えば、整数 4780 は ASCII 文字列 "000012ac" という表現になります):

フィールド名   フィールドサイズ   意味
--------------------------------------------------------------------------------
c_magic         6 バイト          文字列 "070701" もしくは "070702"
c_ino           8 バイト          ファイルの inode 番号
c_mode          8 バイト          ファイルのモードとパーミッション
c_uid           8 バイト          ファイルのユーザ ID
c_gid           8 バイト          ファイルのグループ ID
c_nlink         8 バイト          リンク数
c_mtime         8 バイト          修正時刻
c_filesize      8 バイト          データフィールドのサイズ
c_maj           8 バイト          ファイルデバイス番号の Major 部
c_min           8 バイト          ファイルデバイス番号の Minor 部
c_rmaj          8 バイト          デバイスノード参照の Major 部
c_rmin          8 バイト          デバイスノード参照の Minor 部
c_namesize      8 バイト          ファイル名の長さ. 末尾の \0 を含む
c_chksum        8 バイト           c_magic が 070702 の場合はデータフィールドの
                                  チェックサム. それ以外の場合はゼロ.

c_mode フィールドは、Linux の stat(2) によって返される st_mode の内容と
同一で、ファイルのタイプとパーミッションを表しています。

通常ファイルでもシンボリックリンクファイルでもないファイルの場合、
c_filesize はゼロになります。

c_chksum フィールドは、データフィールドの全てのバイトを単純に合計した
符号無し 32 ビット値です。cpio(1) はこれを "crc" として参照しますが、
これは明らかに不正確な値です (巡回冗長検査は、ここでのやり方とは異なる、
より強力な整合性検査です)。しかしながら、ここで使用されているアルゴ
リズムはこうなっています。

ファイル名が "TRAILER!!!" の場合、これは実際にはアーカイブ終端マーカと
なります。アーカイブ終端マーカの c_filesize はゼロでなければなりません。


*** ハードリンクの扱い

c_nlink の値が 1 より大きい、ディレクトリ以外のエントリが見つかった場合、
タプルバッファの中から (c_maj, c_min, c_ino) のタプル (組) が検索されます。
当該タプルが見つからない場合は、そのタプルはタプルバッファに入れられ、
当該エントリが通常どおりに作成されます。見つかった場合は、当該ファイルの
二つ目のコピーではなく、ハードリンクが作成されます。ファイルの内容の二つ
目のコピーを含める必要はありません (含めても構いませんが)。ファイルの内容
が含まれていない場合、後ろにデータセクションが続かないことを示すため、
c_filesize フィールドはゼロである必要があります。もしもデータが存在する
ならば、当該ファイルの以前のインスタンスは上書きされます。これにより、
データを含むファイルをどの場所に置いてもよいということになります (GNU
cpio には、最後のファイルインスタンスのみにデータが添付されていると伝え
られます)。

シンボリックリンクファイルの場合、c_filesize はゼロではいけません。

"TRAILER!!!" アーカイブ終端マーカが見つかった場合、タプルバッファはリセット
されます。これにより、別々に作成されたアーカイブを結合することが可能となり
ます。

そういうわけで、異なる場所にあるファイルデータを ((c_maj, c_min, c_ino)
フィールドを再生成することなく) 繋ぎ合わせるためには、下記のテクニックの
いずれかを使うことができます。

a) 個々のファイルデータを "TRAILER!!!" アーカイブ終端マーカで分割する、
   もしくは、

b) ディレクトリではない全てのエントリの c_nlink の値が 1 になるようにする。

------------------------------------------------------------
翻訳団体： JF プロジェクト < http://www.linux.or.jp/JF/ >
翻訳者：   川崎 貴彦 < takahiko(a)hakubi.co.jp >
翻訳日：   2004/02/26
校正者：   小林 雅典 < zap03216(a)nifty.ne.jp >
