Solaris/Linux/FreeBSDでCD-Rを焼こう |
YAMAMORI Takenori ●yamamori |
§研究編 [ISO9660/RockRidge/Jolietの詳細]
通常のCD-ROMは,物理レベルでは“CD-ROM mode 1”です. これをUNIX上から見ると,約650Mバイトのブロックデバイスとして見えます. ここに書き込むデータは,基本的には何でも良く,CD-ROM上にufsなどで ファイルシステムを作っても,あるいはtarなどで直接データを書き込んでも 別に構わないのです.(ただし,データサイズを2kバイトの整数倍にする必要あり)
しかし,CD-ROMはシークが遅く,また読み出し専用であるため, この特徴にうまく適合し,かつ,リムーバルメディアとしてさまざまなOS上で 扱えるように考えられたファイルシステムフォーマットがISO9660です. このためCD-ROMには通常はISO9660で記録します.
ISO9660には,ファイル名の長さ制限などの違いから, Leve1/2/3の3種類が存在しますが, 普通,ISO9660といえばISO9660 Level 1を指します. ただし,規格上は,ISO9660本来の規格(Level 3と同じ)がまず規定され, それに制限を加える形でLevel 1/2が存在するという順序になっています.
ISO9660のファイルシステムにおいて,ファイル名に使用できる文字は 基本的にはd-characterと呼ばれるもので, これは,英大文字・数字と'_'(アンダースコア)です.
ただし,“Supplementary Volume Descriptor”が存在する場合は そのエスケープシーケンスによって結果的にd1-characterというものを 定義することができ,これによって,さらに別の文字をファイル名として 使用できるようにもなります.このあたりについては話がややこしくなることから 深入りせず,ISO9660のファイル名としては「英大文字・数字と'_'」のみが 使えるものとして話を進めます.
通常ファイル(ディレクトリを除くファイル)は,ファイル名の中に 必ず'.'を含まなければならず,'.'の左側と,'.'の右側の 拡張子の長さを合わせて30文字以内まで使えます.('.'を 含めて考えると31文字以内)
さらに,拡張子よりも右側に,';'とバージョン番号(1〜32767)を 必ず付けなければなりませんが,この部分の長さは30文字以内の文字数としては カウントしません.
ディレクトリの場合は,逆に'.'や';'を付けることはできず, 31文字以内の文字列がディレクトリ名として使えます. また,ディレクトリの階層の深さは,ルートディレクトリを1と数えて8段階まで のサブディレクトリが使え,それ以上深いディレクトリは掘れません.
通常ファイル: ABCD1234.XYZ;1 ======== === a b a + b ≦ 30 '.'と';'は必ず必要 バージョン番号は;1〜;32767 ディレクトリ: ABCD1234 ======== a a ≦ 31 '.'や';'は付けられない |
以上が,ISO9660本来の規格(Level 3)です. Level 2では,「ファイルを複数のセクションに分割しない」という 制限が加わりますが,ファイルを複数のセクションに分割する方が 特殊なケースであるのと,ファイル名の規則自体は変わらないことから, Level 2とLevel 3は同じものと考えてよいでしょう.
次に説明するのが,最も多く使われるLevel 1です. Level 1ではLevel 2の上にさらに,いわゆるMS-DOSの8.3形式の制限が加わります. つまり,通常ファイルの場合は,'.'より左側が8文字以内, '.'より右側の拡張子が3文字以内です. ただし,“;1”などのバージョン番号は依然として必要です. また,ディレクトリの場合は拡張子無し(“;1”もなし)で8文字以内です. Level 1での典型的なファイル名は,“ABCD1234.XYZ;1”のようになります.
なお,CD-ROMを,RockRidge拡張やJoliet拡張を使わずにマウントした場合, ファイル名の後ろには“;1”が付いているはずですが, デフォルトではOSがそれを取り除いてしまうため見えません.
ところで,ISO9660のLevel 2や3においても,ファイル名の中の'.'の数は, 依然として1個でなければなりません. しかし実際問題,Level 1の,いわゆる8.3形式の枠をはみ出してしまえば, いずれMS-DOSではアクセスできなくなることに変わりはないため, あとは'.'が2個以上あろうと,大文字と小文字が混在してようと, とくに問題が起きないというのも実情のようです.
以上のようにISO9660は各OS間の互換性を重視して規定されていますが, このままでは,ファイル名の制約がかなり厳しく, また,UNIXのパーミッションなども表現できません. そこで,ISO9660と互換性を保ったまま,長いファイル名その他に 対応できるように拡張されたフォーマットが,RockRidge拡張やJoliet拡張です.
UNIXではRockRidge拡張が用いられます. RockRidgeでは長いファイル名の他,以下のように,UNIX特有の各種ファイル属性も 表現されます.深いディレクトリはリロケートして回避します.
RockRidgeでは,ISO9660の各ディレクトリレコードの後ろのエリアに, “NM”(ファイル名),“PX”(パーミッション/uid/gid)などの RockRidgeのエントリを追加することにより フォーマットを拡張しています.
深いディレクトリについては,ISO9660レベルでは,あくまで8階層までとし, それを越えるディレクトリは,ルートディレクトリ直下に“rr_moved”という ディレクトリ(mkisofsの場合)を作り,その下に再配置します. これを,RockRidgeの,“CL”,“PL”,“RE”というエントリを用いて, 再度,元のディレクトリツリーの形に結合します.
ただし,RockRidgeでマウントしても“rr_moved”ディレクトリ自身は, 空のディレクトリとして見えてしまいます.
Joliet拡張はWindows系で用いられ,ファイル名はUnicodeを使って64文字まで 使えるようになります.(1文字2バイトなので,バイト数では128バイトまで) 漢字ファイル名もUnicodeで記録されます.
ディレクトリの階層の深さの制限についても, 単にその制限を無くすことによって対応しています.
RockRidgeでは,あくまでISO9660のディレクトリレコードをそのまま用い, それを追加データで拡張するという方式なのに対し, Jolietでは,“Primary Volume Descriptor”(PVD)の他に, “Supplementary Volume Descriptor”(SVD)を別に設け, ディレクトリレコードも,パステーブルも,Joliet用のものを一式 ISO9660とは別に用意することにより,フォーマットを拡張しています.
Jolietに対応したOSは,JolietのSVDを見つけると,PVDを無視して, JolietのSVDを用いてファイルシステムを認識します.
なおパステーブルは,ディレクトリ検索を高速化するためのもので, パステーブルを使わなくてもディレクトリレコードのデータには到達できます.
以上のデータの配置を以下に示します.
0x0000 +--------------------------+ | (空きエリア) | 0x8000 +--------------------------+ -−|− PVD | | +--------------------------+ | | El Torito | | +--------------------------+ | | SVD (Joliet) ---|−- | +--------------------------+ | |→| ISO9660 | | | | パステーブル | | | +--------------------------+ | | | Joliet |←| | | パステーブル | | | +--------------------------+ | -→| ISO9660(RockRidge) | | -−|− ディレクトリレコード | | | +--------------------------+ | | | Joliet |←- | | ディレクトリレコード −|−- | +--------------------------+ | | +--------------------------+ | |→| ファイル本体 |←| | +--------------------------+ | |→| ファイル本体 |←| | +--------------------------+ | : : : : : : |