FATファイルシステム(その2)
FATファイルシステムの構造(続き)
FAT(File Allocation Table)
FATは、BPBに続く領域に配置されている。FATが存在するセクタ番号は次のように計算することができる。
FirstFATSector = 1st_sector + BPB_RsvdSecCnt
FATは複数個存在する場合、2個目のFATが存在するセクタは
FirstFATSector + BPB_FATSz16
で計算することができる。
FATの例
FAT16では、上の例のように16bit(2バイト)で一つの要素になっていて、ユーザファイルの場所(クラスタ番号)を示す連結リストになっている。
RDEとFAT
RDEのFstClusLO(クラスタ番号)は、ファイルの先頭が存在するクラスタ番号を示しており、上の例では0x0002である。これは、ファイルの先頭がクラスタ2に存在することを示している。
FATテーブルのクラスタ2には、0x0003と記録されている。これはファイルの続きがクラスタ3に存在することを示している。
同様にFATの連結リストをたどっていくと、クラスタ5の0xffffに出会う。0xffffは連結リストの終了を意味している。
よって、上の例ではSAMPLE.TXTの格納場所はクラスタ2→クラスタ3→クラスタ4→クラスタ5の順に、4つのクラスタに分かれていることになる。
※クラスタ0とクラスタ1は使われていない。ユーザデータ領域はクラスタ2が先頭になるので注意が必要である。
— 演習 —
First_FAT_sect を計算し、FAT を取得する関数 get_FAT() を完成せよ。
ユーザデータ
ユーザデータはRDEに続く領域に位置していて、先頭セクタは次のように計算することができる。
FirstDataSector = FirstRDESector + ( 32 * BPB_RootEntCnt ) / BPB_BytesPerSec
ここで、32は1エントリあたりのバイト数、BPB_RootEntCntはRDEにエントリ可能なファイルやディレクトリの数であるから、32 * BPB_RootEntCntはRDEのサイズ(バイト)である。
これをBPB_BytesPerSec(セクタあたりのバイト数)で割ると、BPBに必要なセクタ数になる。
ユーザデータは、セクタではなく、クラスタ単位で管理されている。BPB_SecPerClusは1クラスタあたりのセクタ数である。例えばBPB_SecPerClus = 2であれば、1クラスタあたり2セクタである。
ユーザデータ領域の先頭はクラスタ2であり、クラスタ0とクラスタ1は存在しない。
クラスタ2の先頭セクタは上で計算した値(FirstDataSector)であり、クラスタ3の先頭セクタはFirstDataSector + BPB_SecPerClusである。
クラスタNの先頭セクタは
FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector
で計算することができる。
FATの例(複数のファイル)
複数のファイルが存在する場合のRDEとFATを次に示す。
RDEの例
FATの例
この例ではFILE1.TXT, FILE2.TXT, FILE3.TXT, FILE4.TXTの4つのファイルが存在している。
RDEとFATの抜粋
RDEによると、FILE1.TXTはクラスタ2に存在している。FATによると、クラスタ2に続くクラスタは無い。よって、FILE1.TXTはクラスタ2に全て格納されている。
クラスタ2は512*2バイトであるが、全てを使用しているのではない。RDEのFileSize分だけが有効なデータとして使われていて、クラスタの残りの部分は空きになっている。
同様に、FILE4.TXTはクラスタ6に存在している。FATによると、クラスタ6の次はクラスタ7、クラスタ7の次はクラスタ8、クラスタ8の次はクラスタ9となっている。クラスタ9はクラスタチェーンの最後である。よって、FILE4.TXTはクラスタ6→クラスタ7→クラスタ8→クラスタ9の4つのクラスタに記録されている。
FATの例(ファイル削除)
ファイルを削除した場合のRDEとFATの変化は以下のようである。
削除前のRDE
削除前のFAT
この状態で、FILE3.TXTを削除する。FILE3.TXTはクラスタ4→クラスタ5に存在しているファイルである。
削除後のRDE
削除により、RDEのFILE3.TXTのエントリ部分のファイル名の先頭の1文字が0xe5に変化している。ファイル名の先頭が0xe5のとき、このエントリは無効であると判断され、ファイルがルートディレクトリから消える。
削除後のFAT
削除により、FILE3.TXTが使用していたクラスタ4とクラスタ5のFATは0x0000となり、クラスタは未使用となる。
このように、ファイルを削除する場合は、データ自体を消去するのではなく、ディレクトリエントリのファイル名に未使用のマークをし、FATテーブルの該当部分を解放するだけである。
— 演習 —
演習1:FATを読み、RDEに登録されているファイルのデータが記録されているクラスタ番号を表示する関数 ex_FAT() を完成せよ。
- RDEに登録されているファイルそれぞれについて、クラスタ番号を表示する。複数のクラスタが使われている場合は、クラスタチェーンをたどり、すべてのクラスタ番号を表示する。
演習2:PCを使いSDカードに簡単なテキストファイルをコピーしておき、それを取得する関数 get_File() を完成せよ。
- 取得したファイルは File.Data[] に格納する
- RDEから得たファイルサイズ分だけ取得すること
- 取得したテキストファイルは関数 print_File() で表示する