Twenty-five on Web
このページの最終更新日: 2001/12/17 >戻る
FAT32 memo

このページについて

このページは,自分の後生(?)のために FAT32 について得た知識について覚書をしているものです。
情報は主に他サイトから得たものを中心としてできるだけ見たまま掲載しているつもりですが,それが正しい保証はどこにもありませんのでご注意ください。

以下,2Bytes 以上の数値はすべてリトルエンディアンです。


論理ディスクの構造

論理ディスクは以下のようなもので構成されている。

ブートセクタ
論理ディスクのパラメータや,ブートのために必要なプログラムが書き込まれている領域。論理ディスクの先頭にある。

FAT 領域
クラスタ順に FAT が書き込まれている。普通は同じものが2つ連続して存在する。

ルートディレクトリエントリ
ルートディレクトリのディレクトリエントリ。FAT32 からは FAT 領域の直後である必要がなくなったが,普通は FAT 領域の直後にある。

データ領域
データやサブディレクトリエントリが含まれる。

順番も上のとおりで,それぞれの大きさ(セクタ数)はブートセクタに書き込まれているパラメータから決定できる。


BPBの詳細

BPB (BIOS Parameter Block) はブートセクタの先頭にあるディスクパラメータのことである(普通 BPB といったら Offset 0Bh 以降を指す)。DOS が管理する情報とあわせて DPB (Device Parameter Block)ということもある。

BPB の詳細は以下のとおりである。ちなみに,うちのハードディスクのブートセクタの最初はこんな感じ(半角文字はすべてスペースに変換してある)。

            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
           -----------------------------------------------
[00000000] EB 58 90 4D 53 57 49 4E 34 2E 31 00 02 40 20 00 | ・信SWIN4.1  @  
[00000010] 02 00 00 00 00 F8 00 00 3F 00 FF 00 3F 00 00 00 |         ?   ?   
[00000020] 3D 36 49 04 49 22 00 00 00 00 00 00 02 00 00 00 | =6I I"          
[00000030] 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 |                 
[00000040] 80 01 29 D6 19 03 36 57 49 4E 44 4F 57 53 5F 58 |   )   6WINDOWS_X
[00000050] 50 20 46 41 54 33 32 20 20 20 33 C9 8E D1 BC F4 | P FAT32   3 紗  

Offset: 00, Size: 3 - ジャンプ命令
OS をロードするためのジャンプ命令が書き込まれる。8086 の Near Jump 命令が EB xx xx 。

Offset: 03h, Size: 8 - OEM ラベル名
フォーマットを行った OS やバージョン。 Windows95 OSR2 以降は「MSWIN4.1」で,それ以前の Windows95 は「MSWIN4.0」。FAT16 は「MSDOS5.0」など。

Offset: 0Bh, Size: 2 - 論理セクタサイズ
論理ドライブの1セクタあたりのバイト数。通常は 0200h (512バイト/セクタ)。

Offset: 0Dh, Size: 1 - 1クラスタ(アロケーションユニット)あたりのセクタ数
01h, 02h, 04h, 08h, 10h, 20h, 40h, 80h のいずれかが使用される。

Offset: 0Eh, Size: 2 - 予約セクタ数
セクタ 0 から FAT 領域の直前までのセクタ数。すなわち,メイン FAT の開始セクタ番号をあらわす。

Offset: 10h, Size: 1 - FAT の数
ディスクに存在する FAT の組の数を表す。普通は 2 。

Offset: 11h, Size: 2 - ルートディレクトリエントリの最大数
FAT12/16 用であり,FAT32 では常に 0000h となる。

Offset: 13h, Size: 2 - 全セクタ数(Small Sector)
FAT32 では常に 0000h 。全セクタ数が WORD(2バイト) で表される場合のみ使われる。

Offset: 15h, Size: 1 - メディアディスクリプタ
メディアの種類を示すフラグ。以下の数値が使用される。

容量
メディアサイズ・大きさ
F0h
2.88MBytes
3.5インチ, 両面, 36セクタ
F0h
1.44MBytes
3.5インチ, 両面, 18セクタ
F9h
720KBytes
3.5インチ, 両面, 9セクタ
F9h
1.2MBytes
5.25インチ, 両面, 15セクタ
FDh
360KBytes
5.25インチ, 両面, 9セクタ
FFh
320KBytes
5.25インチ, 両面, 8セクタ
FCh
180KBytes
5.25インチ, 片面, 9セクタ
FEh
160KBytes
5.25インチ, 片面, 8セクタ
F8h
--
固定ディスク

Offset: 16h, Size: 2 - FAT のセクタ数
FAT12/16 用であり,FAT32 では常に 0000h となる。

Offset: 18h, Size: 2 - 1トラックあたりのセクタ数
Offset: 1Ah, Size: 2 - ドライブのヘッド数
ドライブの物理的な情報をあらわすパラメータ。

Offset: 1Ch, Size: 4 - 不可視セクタ数
論理ドライブの先頭セクタ直前までの物理ドライブのセクタ数。

Offset: 20h, Size: 4 - 全セクタ数(Large Sector)
Small Sector フィールドが 0 のときに使われるフィールド。すなわち,FAT32 ではこちらにセクタ数が書き込まれる。

Offset: 24h, Size: 4 - 1つの FAT あたりのセクタ数(FAT32)

Offset: 28h, Size: 2 - メディアディスクリプションフラグ(FAT32)
通常は 0000h が書き込まれており,ミラーリングを行うと bit7 が 1 になって bit3-0 にアクティブ FAT 番号が入る。

Offset: 2Ah, Size: 2 - ファイルシステムバージョン(FAT32)
0000h が書き込まれる。今後の拡張のための予約エリア。

Offset: 2Ch, Size: 4 - ルートディレクトリの開始クラスタ(FAT32)
特に意図的に移動しない限りは 00000002h が書き込まれ, FAT 領域の直後になる。

Offset: 30h, Size: 2 - ファイルシステム情報のセクタ番号(FAT32)
FSINFO のセクタ番号を示す。

Offset: 32h, Size: 2 - ブートセクタのコピーのセクタ番号(FAT32)
論理ドライブの先頭セクタが壊れているときに使われるブートセクタのコピーの位置を示す。

Offset: 34h, Size: 6 - 予約エリア(FAT32)

Offset: 40h(FAT32), 24h(FAT12/16), Size: 1 - 物理ドライブ番号
ハードディスクの場合 80h が書き込まれるのが普通。

Offset: 41h(FAT32), 25h(FAT12/16), Size: 1 - 予約エリア

Offset: 42h(FAT32), 26h(FAT12/16), Size: 1 - ブートシグネチャ
29h の場合はボリュームシリアル番号を持つ。

Offset: 43h(FAT32), 27h(FAT12/16), Size: 4 - ボリュームシリアル ID
フォーマット時にランダムに割り当てられるシリアルナンバー。

Offset: 47h(FAT32), 2Bh(FAT12/16), Size: 11 - ボリュームラベル

Offset: 52h(FAT32), 36h(FAT12/16), Size: 8 - ファイルシステムタイプ
「FAT32」/「FAT16」/「FAT12」のうちいずれかが書き込まれる。


FSINFO

FAT32 では,論理セクタ番号 1 に FSINFO と呼ばれる領域を持っている。これまでの FAT においては,空き容量を計算するためには FAT をすべて読み出して未使用クラスタ数を数えなければならなかったが, FAT32 ではこの FSINFO に空きクラスタ数を書き込むことで空き容量の計算速度が向上している。

ちなみに,うちのハードディスクの FSINFO エリアはこんな感じ。

            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
           -----------------------------------------------
[000001E0] 00 00 00 00 72 72 41 61 58 72 0C 00 3E 18 00 00 |     rrAaXr >    
[000001F0] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA |               U 

論理セクタ番号 1
Offset: 1E4h, Size: 4 - ファイルシステムシグネチャ
61417272h 'rrAa' 固定。

Offset: 1E8h, Size: 4 - 空きクラスタ数
空きクラスタが計算されていないときは -1 (FFFFFFFFh) が書き込まれている。

Offset: 1ECh, Size: 4 - 最終書き込みクラスタ番号

Offset: 1F0h, Size: 6- 予約エリア


FAT 領域

FAT 領域は,各 FAT エントリが対応するクラスタ順に並んで書き込まれている領域である。各 FAT エントリはクラスタに1対1で対応しており, FAT エントリを参照することで対応するクラスタがどのような状態(使用中,空きなど)であるかを知ることができる。

1 クラスタのサイズを超えるファイルをディスクに書き込むときに,ファイルをクラスタサイズ(たとえば 4kBytes)ごとに分けて書き込む必要が生じる。このときにファイルの先頭の 4kBytes が書き込まれたクラスタの番号はディレクトリエントリ(後述)に記録されるが,その次の 4kBytes が書き込まれたクラスタがどこにあるかを記録しておかないとそのファイルを読み出すことができない。そこで FAT ファイルシステムでは,ファイルの先頭のクラスタに対1~$9$k FAT エントリに,その次のクラスタの番号を記録しておくことで「クラスタの鎖(クラスタチェーン)」をつくり,ファイルの記録を行っている。

たとえば,あるファイルの先頭クラスタ番号が 3 であると記録されていたら,クラスタ番号 3 の内容とともにそれに対応する FAT エントリを読み込む。 FAT エントリに 5 と書かれていれば,そのファイルの続きはクラスタ番号 5 に記録されているということになる。さらに,クラスタ番号 5 の FAT エントリに 9 と書かれていれば,そのファイルの続きはクラスタ番号 9 に記録されている。こんな要領である。なお, FAT エントリに書き込まれている数値には特殊な意味を持つものがあり,「ファイル終了」「空き」「不良」などである。今の例でクラスタ番号 9 の FAT エントリにファイル終了サインが書き込まれていれば,クラスタ番号 9 でファイルが収まっているということを示す。

FAT 領域の開始セクタと 1 つの FAT あたりのセクタ数は BPB に記録されている。この領域内において FAT エントリは(開始セクタのオフセット 0 から)クラスタ順に並べられる。ただし,クラスタ番号 0 と 1 は予約されており FAT エントリに書き込まれる内容も決まっている。実際に利用されるクラスタ番号は 2 からである(通常ルートディレクトリエントリに使用される)。

            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
           -----------------------------------------------
[00000000] F8 FF FF 0F FF FF FF 7F FF FF FF 0F FF FF FF 0F |                 
[00000010] 06 00 00 00 FF FF FF 0F FF FF FF 0F FF FF FF 0F |                 
[00000020] FF FF FF 0F 77 00 00 00 0B 00 00 00 FF FF FF 0F |     w           
[00000030] 12 0F 00 00 FF FF FF 0F FF FF FF 0F FF FF FF 0F |                 
[00000040] FF FF FF 0F FF FF FF 0F 6E 06 00 00 FF FF FF 0F |         n       
[00000050] FF FF FF 0F FF FF FF 0F FF FF FF 0F FF FF FF 0F |                 
[00000060] FF FF FF 0F FF FF FF 0F FF FF FF 0F FF FF FF 0F |                 
[00000070] FF FF FF 0F 93 02 00 00 FF FF FF 0F FF FF FF 0F |                 
[00000080] FF FF FF 0F 9C 00 00 00 FF FF FF 0F FF FF FF 0F |                 

FAT 領域の先頭はこんな感じ。 FAT32 のクラスタ番号は 4Bytes であらわされるので,FAT エントリも 4Bytes ずつ区切って読み出されることになる。上の Offset 10h, Size 4 のエントリはクラスタ番号 4 のエントリで,クラスタ番号 6 が続いていることを示している。

FAT エントリの数値の意味は次のとおり。

00000000h 未使用クラスタ
00000002h 〜 0FFFFFF6h ファイルの次のクラスタ
0FFFFFF7h 不良クラスタ
0FFFFFF8h 〜 0FFFFFFFh ファイルの最終クラスタ(通常は 0FFFFFFFh が使用される)

ディレクトリエントリ

ディレクトリエントリはそのディレクトリ内にあるファイルの情報を記録する場所である。ルートディレクトリの情報はルートディレクトリエントリに記録され,通常はクラスタ番号 2 に存在する。その他のディレクトリエントリはデータ領域に記録される。下層のディレクトリエントリの場所は,その上層のディレクトリエントリに記録されている。たとえば, \Windows\System\ のディレクトリエントリの位置は \Windows\ のディレクトリエントリに記録されている。

ディレクトリエントリは先頭から各ファイルごとに 32Bytes ずつ割り当てられ,後述のような情報が記録されている。ディレクトリのファイルが多いなどで,ディレクトリエントリが 1クラスタに収まらない場合には,通常のファイルのようにクラスタチェーンを作成することで別のクラスタにその続きを作ることができる。(memo: FAT16 以前ではルートディレクトリエントリの領域はシステムエリアとなっていて,クラスタチェーンによる拡張はできない。すなわちルートディレクトリにおけるファイルの数に制限がある。) ただし,ディレクトリエントリの先頭には「このディレクトリ」をあらわす '.' というファイルと,「1つ上層のディレクトリ」をあらわす '..' というエントリが書き込まれる。

            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
           -----------------------------------------------
[000000C0] 42 4F 4F 54 20 20 20 20 49 4E 49 26 18 69 23 92 | BOOT INI&・i#窒 [000000D0] 82 2B 90 2B 05 00 01 9A 82 2B C6 D6 C1 00 00 00 | + + 嘯+ [000000E0] 42 20 00 53 00 65 00 74 00 74 00 0F 00 4A 69 00 | B S e t t Ji [000000F0] 6E 00 67 00 73 00 00 00 FF FF 00 00 FF FF FF FF | n g s [00000100] 01 44 00 6F 00 63 00 75 00 6D 00 0F 00 4A 65 00 | D o c u m Je [00000110] 6E 00 74 00 73 00 20 00 61 00 00 00 6E 00 64 00 | n t s a n d [00000120] 44 4F 43 55 4D 45 7E 31 20 20 20 10 00 3D 42 92 | DOCUME~1 =B窒 [00000130] 82 2B 88 2B 00 00 43 92 82 2B E6 50 00 00 00 00 | + + C窒+覬

Offset: 00h, Size: 8 - ファイル名
Offset: 08h, Size: 3 - 拡張子
MS-DOS 形式 8.3 ファイル名が記録される。それぞれ 8文字,3文字に満たない場合は残りがスペース(20h)で埋められる。先頭バイトが E5h のとき,そのファイルが削除済みであることを示す。

Offset: 0Bh, Size: 1 - ファイル属性
以下の数値の和であらわされる。

01h
読み取り専用
02h
隠しファイル
04h
システムファイル
08h
ボリュームラベル
10h
ディレクトリ
20h
ファイル

Offset: 0Ch, Size: 1 - 予約エリア
大小文字フラグとして WindowsNT で使用される…らしい。

Offset: 0Dh, Size: 1 - 作成時刻(10ms単位)(VFAT)
おそらく2秒間隔の作成時刻を補完するものと思われる。

Offset: 0Eh, Size: 2 - 作成時刻(VFAT)
Offset: 10h, Size: 2 - 作成日付(VFAT)
Offset: 12h, Size: 2 - アクセス日付(VFAT)

Offset: 14h, Size: 2 - ファイルの先頭クラスタ番号の上位 2Bytes (FAT32)

Offset: 16h, Size: 2 - 更新時刻
Offset: 18h, Size: 2 - 更新日付

Offset: 1Ah, Size: 2 - ファイルの先頭クラスタ番号の下位 2Bytes

Offset: 1Ch, Size: 2 - ファイルサイズ

時刻のフォーマット :
bit15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
時(0-23)
分(0-59)
秒(0-29) 実際は2倍する

日付のフォーマット :
bit15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
(1980からの年数)
月(1-12)
日(1-31)


●ロングファイルネームのディレクトリエントリ
(詳しくは省略します)

Offset: 00h, Size: 1 - シーケンスバイト
下位 6bits でサブエントリ番号を示し, bit6 が立っていると最後のエントリであることを示す。

Offset: 01h, Size: 10 - Unicode ファイル名
Offset: 0Bh, Size: 1 - 属性 (0Fh固定)
Offset: 0Ch, Size: 1 - ロングエントリタイプ (00h固定)
Offset: 0Dh, Size: 1 - 短いファイルネームのチェックサム
Offset: 0Eh, Size: 12 - Unicode ファイル名(続き)
Offset: 1Ah, Size: 2 - 予約エリア (0000h固定)
Offset: 1Ch, Size: 4 - Unicode ファイル名(続き)


その他の情報

●クラスタサイズについて

クラスタサイズはフォーマットの方法や領域の大きさに応じて自動的に決定される。FAT32 ドライブの場合, 8GBytes 未満の領域は 1クラスタ 4kBytes,8GBytes 以上 16GBytes 未満の領域は 8kBytes,16GBytes 以上 32GBytes 未満の領域は 16kBytes,それ以上は 32kBytes となっている。ただし,このクラスタサイズはフォーマットのオプションにより変更することができる。

Windows9x 系の format コマンドなら,「format X: /Z:(セクタ数)」とするそうである(今手元にないので分からない)。WindowsXP では /A で変更できる(/? の usage で表示される)。FAT32 のポテンシャルから,1TBytes までの領域ではクラスタサイズ 4kBytes が可能である。

●クラスタ番号から論理セクタ番号を計算する(またはその逆)

論理セクタ番号 = (クラスタ番号 - 2) × (1クラスタあたりのセクタ数) + (1つの FAT あたりのセクタ数) × (FAT の数) + (予約セクタ数)

●サポートする最大サイズ

2TBytes/領域。これはセクタ数が DWORD (4Bytes) であらわされているのと関係があると思われる(FFFFFFFFh × 512Bytes = 2TBytes)。


ZOUDA Shumpei
<s-zouda at triaez.kaisei.org>
made with CSS Valid CSS! Valid HTML 4.01!