はじめに
ファイルシステムについて学び始めたばかりなので最近見かけない学びやすそうなFAT16
について勉強していったので自分用のメモとしてまとめました。
FATファイルシステムについて
FATファイルシステムは最初にMS-DOSでサポートされていたファイルシステムで様々なリムーバブルディスクで使用されているファイルシステムです。
FATというのはFile Allocation Tableの略称でディスク内でのファイルの位置、データの割り当てられた領域を管理するシステムのことを言います。
FAT12、FAT16、FAT32の数字はFAT領域で扱うデータ長のことです。
FATファイルシステムは情報が格納されている場所をセクタ番号で表します。
領域について
FATファイルシステムには基本的に下記のような3~4個の領域があります。
- 予約領域 ←今回はこの領域についての話です!
- FAT領域
- ルートディレクトリ領域(FAT32ではこの領域はありません)
- データ領域
※FATファイルシステムのデータ構造は全てリトルエンディアンです。
予約領域
最初のセクタに格納されているのは予約領域です。
予約領域にはBPB(BIOS Parameter Block)やブートストラップコード等が書かれています。
BPBにはセクタ長や1クラスタのセクタ数、各領域の開始位置などの値が格納されていて、各領域のサイズが計算できるようになっています。
この領域を見るときに注意することは、ブートシグネチャは予約領域の最後の2バイトが0xAA55なのではなく、オフセット0x01FEは0x55、0x01FFが0xAAと決まっていることです。
資料によっては、予約領域の最後の2バイトにブートシグネチャが格納されていると書かれていることがありますが、間違いなので注意してください。
1セクタに格納されるバイト数は互換性のために512バイトが推奨されていますが、ハードウェアによって、バイト数が512より大きい場合は1024、2048、4096のどれかになります。もし512バイトよりも、1セクタのバイト数が大きかったとしても、ブートシグネチャのオフセットは変わりません。
ですが、シグネチャが正しく設定されている場合には、終わり2バイトが0xAA55でも問題ありません。
フィールド名の先頭にBSが書かれているのはブートセクタ内のフィールド、BPBが表記されているものはBPB内のフィールドです。
フィールド名 | オフセット | サイズ(byte) | 説明 |
---|---|---|---|
BS_JmpBoot | 0x0000 | 3byte | ブートストラップコードへのジャンプ命令が書かれている。 |
BS_OEMName | 0x0003 | 8byte | ボリュームをフォーマットしたシステムが書かれている。 |
BPB_BytsPerSec | 0x000B | 2byte | 1セクタあたりのバイト数。セクタ長。512が推奨値。 ハードウェアによっては1セクタのバイト数が1024、2048、4096のいづれかになる。 |
BPB_SecPerClus | 0x000D | 1byte | 1クラスタあたりのバイト数。32kバイト以下でなければならない。 |
BPB_RsvdSecCut | 0x000E | 2byte | 予約領域のセクタ数。FAT12/16では1が設定されていなければいけない。 ボリュームの先頭から、このBPB_RsvdSecCutの値分のセクタが予約領域になる。 |
BPB_NumFATs | 0x0010 | 1byte | FATの個数。FAT領域は冗長化のために複数個のFAT領域を持たせることができ、この値は常に2が推奨されている。 |
BPB_RootEntCnt | 0x0011 | 2byte | ルートディレクトリの内のディレクトリエントリ数。32byteエントリの数。 |
BPB_TotSec16 | 0x0013 | 2byte | ボリュームの総セクタ数。全ボリュームのセクタ数のこと。 FAT32では必ずこの領域には無効値(0)を格納し、BPB_TOtSec32を使用している。 |
BPB_Media | 0x0015 | 1byte | メディアIDが格納される。HDD(固定ディスク)は0xF8、あとはフロッピーディスクの媒体の種類によって分かれているが、今はあまりこの値は使われていない。 |
BPB_FATSz16 | 0x0016 | 2byte | 1つのFAT領域に使われるセクタ数が格納される。総クラスタ数に必要な分に満たない場合はクラッシュする。FAT32では必ずこの領域には無効値(0)を格納し、BPB_FATSz32が使用される。 |
BPB_SecPerTrk | 0x0018 | 2byte | 1トラックあたりのセクタ数。 IBMのPCで使用されているディスクBIOS以外では使われない。 |
BPB_NumHeads | 0x001A | 2byte | ヘッドの数。 IBMのPCで使用されているディスク以外のBIOSでは使われない。 |
BPB_HiddSec | 0x001C | 4byte | 分割パーティションがある場合にはここに値が入る。FAT12はシングルパーティションなのでフロッピーディスクなどパーティションの存在しないものは常に0になる。 |
BPB_TotSec32 | 0x0020 | 4byte | ボリュームの総セクタ数。全ボリュームのセクタのこと。 |
FAT12/16とFAT32ではここから内容が変わっていきます。
フィールド名 | オフセット | サイズ(byte) | 説明 |
---|---|---|---|
BS_DevNum | 0x0024 | 1byte | IBMのPCのディスクBIOSで使われるドライブ番号。 |
BS_Reserved1 | 0x0025 | 1byte | WindowsNT用の予約領域。フォーマット時は0にすべき。 |
BS_BootSig | 0x0026 | 1byte | 拡張ブートシグネチャ(0x0029)。 この値が入ることで以下の3つのフィールドが存在することを示す。 |
BS_VolID | 0x0027 | 4byte | ボリュームのシリアル番号。 |
BS_VolLab | 0x002B | 11byte | ボリュームラベル。ルートディレクトリの11バイトのボリュームラベルと一致するため、どちらかを更新するときは常に一致させるべき。 |
BS_FileSysType | 0x0036 | 8byte | 使用されているファイルシステム名が書いてある。 FATファイルシステムの種類の識別には関係ないとされている。 FATドライバによってはここに入っている値が使用される場合もあるので使用しているFATファイルシステムを設定すべき。 |
BS_BootCode | 0x003E | 448byte | OSを起動するまでのプログラム。ブートストラッププログラム。 |
BS_BootSign | 0x01FE | 2byte | このブートシグネチャ(0xAA55)があることによって、ブートセクタが有効であると認識される。ない場合は、そのブートセクタは無効となる。 |
参考資料
http://elm-chan.org/docs/fat.html
http://free.pjc.co.jp/fat/mem/fatm161.html