顕微鏡下のCPIO

cpio CPIOはかなり古い(1990年)ですが、同時に非常に便利なバージョンのアーカイブです。 それは非常に単純であり、したがって、おそらく、普及しています。 たとえば、この形式はRPM、Linuxカーネルのinitramfs、Appleのpaxアーカイブインストーラーで使用されます。



このアーカイブを使用すると、任意の数のファイル、ディレクトリ、およびその他のファイルシステムオブジェクト(シンボリックリンクなど)をバイトの単一ストリームに収集できます。



このアーカイブの形式の例を見てみましょう。



このようなアーカイブ内の各ファイルシステムオブジェクトは、基本的なメタデータを持つヘッダーと、それに続くオブジェクトへのフルパスとこのオブジェクトのコンテンツで構成されます。 ヘッダーには、* nixシステムのstat(2)ファイル構造のフィールドをほぼ繰り返す整数​​値のセットが含まれています。 アーカイブの最後には、「TRAILER !!!」という名前の特別なエントリ(他のエントリと同様)が付いています。



ファイル形式


現時点では、最も一般的なのは古い形式のCPIOファイルエントリです。 彼の説明が与えられます。



記録フォーマットヘッダーの構造は次のとおりです。



struct header_old_cpio { unsigned short c_magic; unsigned short c_dev; unsigned short c_ino; unsigned short c_mode; unsigned short c_uid; unsigned short c_gid; unsigned short c_nlink; unsigned short c_rdev; unsigned short c_mtime[2]; unsigned short c_namesize; unsigned short c_filesize[2]; };
      
      





ここでは、unsigned short型のサイズは16ビットであると想定されています。



c_magic

070707(8進数のCC)、または0x71c7(16進数のCC)に等しい整数値。 バイト順を決定するために使用されます(リトルエンディアンとビッグエンディアン)。



c_devc_ino

ディスクのデバイスとiノード(inode)の番号。 stat構造体の値と一致します。 iノードの値が65535より大きい場合、最上位ビットは失われます。



c_mode

このフィールドは、アクセス権とオブジェクトのタイプを同時に決定します。

0170000 ファイルタイプビットをマスクします
0140000 ソケット
0120000 シンボリックリンク。 シンボリックリンクの場合、リンク本体には、参照先のファイルへのパスが含まれます。
0 100 000 通常ファイル
0060000 特殊ブロック装置
0040000 カタログ
0020000 特殊キャラクターデバイス
0010000 名前付きパイプ(名前付きパイプ)またはキュー(FIFO)。
0004000 SUID
0002000 SGID
0001000 スティッキービット。
0000777 下位9ビットは、オブジェクトへのアクセス権を決定します。


c_uidc_gid

ユーザーIDとファイル所有者グループ。



c_nlink

このファイルへのリンクの数。 ディレクトリの場合、このフィールドの値は常に少なくとも2です。



c_rdev

特殊文字およびブロックデバイスのみ。 フィールドには

関連するデバイス番号。 他のすべてのファイルタイプの場合、値

このフィールドはゼロでなければなりません。



c_mtime

ファイルが最後に変更された時刻。 形式は秒数に対応し、

UNIX時代の始まり以来。 32ビット整数は、2つの配列として書き込まれます

16ビット整数:最初に高位、次に低位。



c_namesize

端末のNULLを含むファイルへのフルパスの長さ。



c_filesize

ファイルサイズ



ヘッダーの直後がオブジェクトへのフルパスです。 パス行の長さが2のべき乗の倍数でない場合、最後に別のNULLが追加されます。 次に、ファイルの内容が配置されます。 コンテンツのサイズが2のべき乗の倍数でない場合、ゼロが埋め込まれます。



アーカイブの例。


では、顕微鏡を見てみましょう。 ブレスを顕微鏡として取ります。 この16進エディタが本当に好きだとは言いませんが、好きなエディタの名前を忘れてしまいました。



単純なディレクトリを作成します。



 cpio_test | + test.txt | + testl.txt
      
      







ここで、testl.txtはtest.txtファイルへのシンボリックリンクです。

test.txtファイルの内容:

 Simple example of cpio usage.
      
      





次に、アーカイブを作成します。

 $ find cpio_test | cpio -ov > example.cpio
      
      





作成したアーカイブをお気に入りの16進エディタで開きます。



私にとって、このアーカイブは次のようになります。

 0000 | C7 71 09 08 9A 34 FD 41 F4 01 F4 01 02 00 00 00 | .q...4.A........ 0010 | 8C 4E 09 31 0A 00 00 00 00 00 63 70 69 6F 5F 74 | .N.1......cpio_t 0020 | 65 73 74 00 C7 71 09 08 A2 34 B4 81 F4 01 F4 01 | est..q...4...... 0030 | 01 00 00 00 8C 4E 09 31 13 00 00 00 1E 00 63 70 | .....N.1......cp 0040 | 69 6F 5F 74 65 73 74 2F 74 65 73 74 2E 74 78 74 | io_test/test.txt 0050 | 00 00 53 69 6D 70 6C 65 20 65 78 61 6D 70 6C 65 | ..Simple example 0060 | 20 6F 66 20 63 70 69 6F 20 75 73 61 67 65 2E 0A | of cpio usage.. 0070 | C7 71 09 08 9C 34 FF A1 F4 01 F4 01 01 00 00 00 | .q...4.......... 0080 | 8C 4E 1A 2F 14 00 00 00 08 00 63 70 69 6F 5F 74 | .N./......cpio_t 0090 | 65 73 74 2F 74 65 73 74 6C 2E 74 78 74 00 74 65 | est/testl.txt.te 00A0 | 73 74 2E 74 78 74 C7 71 00 00 00 00 00 00 00 00 | st.txt.q........ 00B0 | 00 00 01 00 00 00 00 00 00 00 0B 00 00 00 00 00 | ................ 00C0 | 54 52 41 49 4C 45 52 21 21 21 00 00 00 00 00 00 | TRAILER!!!......
      
      







それでは、理解しましょう。



0x71c7 = 070707-ヘッダーの始まり。 そして、アーカイブを作成するときのバイト順はリトルエンディアンであると既に言うことができます。

0x0809はc_dev-ファイルが配置されているデバイス番号です。

0x349aはc_ino-iノードです。 この場合、シニアランクだけが失われました。

0x41fd = 0040775-c_mode。 つまり、ヘッダーにはアクセス権0775のディレクトリが記述されています。

0x01f4 = 500-c_uid。

0x01f4 = 500-c_gid。

0x0002-c_nlink。 各ディレクトリには少なくとも2つのリンクがあります(。および..)

0x0000-c_rdev。

0x4e8cと0x3109は、32ビットのファイル変更時間値の上位ビットと下位ビットです。 0x31094e8c = 1317810441。

0x000aはディレクトリ名の長さです。

0x00000000-ディレクトリには本文がありません。

次はディレクトリの名前です。



次に、次のレコードのタイトルの直後に続きます。 詳細については説明しません-いくつかの違いにのみ注意してください。

c_mode:0x34a2 = 0100664-これが664の権限を持つ通常のファイルであることを示します。

0x0000001e-ファイルコンテンツのサイズ。

エントリの残りの部分は、ディレクトリの説明とは異なります。



次は、シンボリックリンクの記録です。 シンボリックリンクの内容は、それが指すファイルの名前です。 それ以外の場合、メタデータを含むヘッダーとファイルへのパスは、通常のファイルの構造に似ています。



これが、このようなsuchな方法でCPIOアーカイブが作成される方法です。 将来的には、 Gzipで作成されたファイル形式を同様の方法で検討したいと思います。 特に、cfio + gzipバンドルは、GNU / Linuxカーネルが使用するramfsを作成します。



この記事がお役に立てば幸いです。



関連リンク:

CPIOユーティリティの説明

CPIO形式の説明



All Articles