BPBからFATタイプの決定 | FAT

目次

ブートセクターとBPB

FATボリュームにおける最初の重要なデータ構造はBPB(BIOS Parameter Block)と呼ばれ、ボリュームの予約領域にある最初のセクターに配置されています。このセクターは「ブートセクター」や「ゼロ番セクター」と呼ばれることもありますが、重要なのはボリュームの先頭のセクターにあるという点です。
FATボリュームのブートセクタ内のBPBには、FAT12/FAT16またはFAT32のBPBタイプに対応するすべてのBPBフィールドが必ず含まれている必要があります。これによりFATボリュームの互換性が最大限に確保され、すべてのFATファイルシステムドライバがボリュームを正しく理解してサポートできるようになります。

表:ブートセクターBPBの構造(FAT12/16/32共通部)

スクロールできます
名前オフセット
[バイト]
サイズ
[バイト]
内容
BS_JmpBoot03ブートストラップコードへのジャンプ命令です。このフィールドには2つの形式があります。
0xEB、0x??、0x90
0xE9、0x??、0x??
0x??には任意の値が入ります。
BS_OEMName38OEM名識別⼦です。任意の値に設定できます。通常これはボリュームをフォーマットしたシステムを⽰すものです。
BPB_BytsPerSec112セクターあたりのバイト数です。この値は512、1024、2048、または4096のいずれかになります。
BPB_SecPerClus131割り当て単位あたりのセクター数です。この値は0より大きい2の累乗でなければなりません。有効な値は1、2、4、8、16、32、64、128です。
BPB_RsvdSecCnt142予約領域のセクター数です。このフィールドはゼロ以外の任意の値にすることができます。
BPB_NumFATs161FATの数です。2を設定することを強く推奨します。1以上の値を設定できますが、2を前提としているシステムもあります。2に設定することで、FATの情報を一部ミラーリング化されます。
BPB_RootEntCnt172FAT12およびFAT16ボリュームの場合、このフィールドにはルートディレクトリー内の32バイトのディレクトリーエントリーの数が格納されます。FAT32ボリュームの場合、このフィールドは0に設定する必要があります。FAT12およびFAT16ボリュームの場合、この値は常に32倍した値がBPB_BytsPerSecの偶数倍になるような値を指定する必要があります。互換性を最大限に高めるには、FAT16ボリュームでは512を使⽤する
必要があります。
BPB_TotSec16192ボリューム上の総セクター数です。この数には、ボリュームの4つの領域すべてにおけるセクターの総数が含まれます。
FAT12およびFAT16ボリュームでかつセクターの総数が0x10000未満の場合、BPB_TotSec32は0になります。
FAT32ボリュームの場合、このフィールドは0である必要があります。
BPB_Media212このフィールドの有効な値は0xF0、0xF8、0xF9、0xFA、0xFB、0xFC、0xFD、0xFEおよび0xFFです。
0xF8は固定(非リムーバブル)メディアの標準値です。リムーバブルメディアの場合は、0xF0がよく使⽤されます。
BPB_FATSz16222このフィールドはFAT12/FAT16において、1つのFATが占有するセクタ数を16ビットで表します。
FAT32ボリュームではこのフィールドは0でなければならず、BPB_FATSz32にはFATのサイズカウントが格納されます。
BPB_SecPerTrk242割り込み0x13のトラックあたりのセクター数です。このフィールドはジオメトリー(ボリュームが複数のヘッドとシリンダーによってトラックに分割されている)を持ち、割り込み0x13で表⽰されるメディアにのみ関連します。
BPB_NumHeads262割り込み0x13のヘッド数です。このフィールドは前述のBPB_SecPerTrkで説明したとおり関連しています。このフィールドには、1ベースの「ヘッド数」が含まれます。たとえば1.44MBの3.5インチフロッピードライブでは、この値は2になります。
BPB_HiddSec284このFATボリュームを含むパーティションの前の隠しセクターの数です。このフィールドは通常、割り込み0x13で表⽰されるメディアにのみ関連します。
パーティション化されていないメディアでは、このフィールドは常にゼロにする必要があります。
BPB_TotSec32324ボリューム上の新しい32ビットの総セクター数です。この数には、ボリュームの4つの領域すべてにおけるすべてのセクター数が含まれます。

表:ブートセクターBPBの構造(FAT12/16のオフセット36以降)

スクロールできます
名前オフセット
[バイト]
サイズ
[バイト]
内容
BS_DrvNum361割り込み0x13のドライブ番号です。0x80または0x00に設定してください。
BS_Reserved371予約です。0x00を設定します。
BS_BootSig381拡張ブート署名です。次の2つのフィールドのいずれかがゼロ以外の場合に、0x29を設定します。
BS_VolID394ボリュームシリアル番号です。このフィールドはBS_VolLabと併⽤することで、リムーバブルメディア上のボリュームトラッキングをサポートします。これらの値により、FATファイルシステムドライバは、リムーバブルドライブに間違ったディスクが挿入されたことを検出できます。
このIDは現在日時から生成されます。
BS_VolLab4311ボリュームラベルです。このフィールドは、ルートディレクトリに記録されている11バイトのボリュームラベルと一致します。
ボリュームラベルがない場合、このフィールドの設定は文字列「NO NAME」になります。
BS_FilSysType548「FAT12   」、「FAT16   」または「FAT     」のいずれかの文字列です。この文字列は情報提供のみを目的としており、FATタイプを決定するものではありません。
BS_BootCode624480x00を設定します。
BS_Sign51020x55(オフセット510)と0xAA(オフセット511)に設定します。
-512-BPB_BytsPerSecが512を超える場合、残りを0x00で埋めます。

表:ブートセクターBPBの構造(FAT32のオフセット36以降)

スクロールできます
名前オフセット
[バイト]
サイズ
[バイト]
内容
BPB_FATSz323641つのFATが占有するセクター数です。
BPB_ExtFlags402以下のように設定します。
ビット3-0:アクティブなFATの0から始まる番号。
ビット6-4:予約。
ビット7:0はFATがミラーリングされていることを表します。1はビット0~3で示される1つのFATのみがアクティブであることを表します。
ビット15-8:予約。
BPB_FSVer422上位バイトはメジャーリビジョン番号、下位バイトはマイナーリビジョン番号です。これはFAT32ボリュームのバージョン番号です。現時点では0x0000を設定します。
BPB_RootClus444ルートディレクトリーの最初のクラスター番号を設定します。通常は2です。
BPB_FSInfo482FAT32ボリュームの予約領域にあるFSINFO構造体のセクター番号です。通常は1です。
BPB_BkBootSec5020または6を設定します。ゼロ以外の場合、ブートレコードのコピーボリュームの予約済み領域内のセクター番号を示します。
BPB_Reserved5212予約です。0x00を設定します。
BS_DrvNum641割り込み0x13のドライブ番号です。0x80または0x00に設定してください。
BS_BootSig651予約です。0x00を設定します。
BS_Reserved661拡張ブート署名です。次の2つのフィールドのいずれかがゼロ以外の場合に、0x29を設定します。
BS_VolID674ボリュームシリアル番号です。このフィールドはBS_VolLabと併⽤することで、リムーバブルメディア上のボリュームトラッキングをサポートします。これらの値により、FATファイルシステムドライバは、リムーバブルドライブに間違ったディスクが挿入されたことを検出できます。
このIDは現在日時から生成されます。
BS_VolLab7111ボリュームラベルです。このフィールドは、ルートディレクトリに記録されている11バイトのボリュームラベルと一致します。
ボリュームラベルがない場合、このフィールドの設定は文字列「NO NAME」になります。
BS_FilSysType828文字列「FAT32   」を設定します。この文字列は情報提供のみを目的としており、FATタイプを決定するものではありません。
BS_BootCode32904200x00を設定します。
BS_Sign51020x55(オフセット510)と0xAA(オフセット511)に設定します。
-512-BPB_BytsPerSecが512を超える場合、残りを0x00で埋めます。

各領域の計算

各領域の開始位置とサイズは、BPBのフィールドから算出します。

FAT領域

FAT領域の開始位置(FatStartSector)とサイズ(FatSectors)は次のとおりです。

FatStartSector = BPB_RsvdSecCnt;
FatSectors = BPB_FATSz * BPB_NumFATs;

「BPB_FATSz」にはBPB_FATSz16またはBPB_FATSz32を使用します。

ルートディレクトリー領域

ルートディレクトリーの開始位置(RootDirStartSector)とサイズ(RootDirSectors)は次のとおりです。

RootDirStartSector = FatStartSector + FatSectors;
RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;

「32」はディレクトリーエントリーのサイズを表します。

FAT32ではBPB_RootEntCntはゼロのため、ルートディレクトリー領域はゼロとなります。

データ領域

データ領域はルートディレクトリーの残りとなるため、次のとおりです。

DataStartSector = RootDirStartSector + RootDirSectors;
DataSectors = BPB_TotSec - DataStartSector;

「BPB_TotSec」にはBPB_TotSec16またはBPB_TotSec32を使用します。

FATタイプの決定

FATタイプ(FAT12/16/32)は、ボリューム上のクラスター数(CountofClusters)で決定します。

CountofClusters = DataSectors / BPB_SecPerClus;

端数は切り捨てます。

こうして算出したクラスター数より、下記のようにFATタイプを決定します。

If(CountofClusters < 4085) {
  /* Volume is FAT12 */
} else if(CountofClusters < 65525) {
  /* Volume is FAT16 */
} else {
  /* Volume is FAT32 */
}

FATの仕様としては上のとおりですが、現実には異なっている場合があります。上の境界値付近のクラスター数が得られた場合は注意が必要です。

上記のことがあるため、境界値付近となるようなボリュームの作成は避けるべきです。

コメント

コメントする

CAPTCHA


目次