top >
技術情報 >
MS-FFSについて
|
MS-FFSについて
|
ここでは、Microsoft社が開発したバイト指向方式のMS-FFS(Microsoft Flash
File System Media Control Structure)をもとにして、具体的な例を使いながら説明します。
MS-FFSでは、フラッシュメモリ上のすべてのイレーズブロックの最後にブロックアロケーションストラクチャ(Block Allocation Structure, BAS)という構造体を配置します。
BASは下図のような構造になっています。
|
struct BAS {
struct AS {
byte Status;
byte Offset[3];
word Len;
} Alloc[];
dword BootRecordPtr;
dword EraseCount;
word BlockSeq;
word BlockSeqChecksum;
word Status;
|
┳
┃
┃ 可変部
┃
╋
┃
┃
┃ 固定部
┃
┃
┻
|
|
|
(注) |
byte: |
1バイト |
|
word: |
2バイト |
|
dword: |
4バイト |
|
|
BASの固定部には、下記の各フィールドがあります。
|
■ EraseCount : ブロックの消去回数を示すカウンタ
|
ブロックが消去されるごとにインクリメントされる。フラッシュメモリが初期化された時点では、すべてのBASのEraseCountは1となっている。
|
■ BlockSeq : ブロックの論理番号
|
このイレーズブロックの論理番号を保持している。各イレーズブロックは一意となるように論理番号がふられる。
|
■ Status : ブロックのステータス
|
現在のイレーズブロックの状態を示す。
|
また、可変部には配列Allocの要素であるアロケーションストラクチャ(Allocation Structure, AS)があり、下記の各フィールドを持っています。この配列要素ASは、データ領域がイレーズブロックに割り当てる毎に1個、アドレスの下位に向かって追加されていきます。
■ Status : 割り当てた領域のステータス
|
割り当てた領域の現在の状態を示す。
|
■ Offset : 割り当てた領域のオフセット
|
割り当てた領域のイレーズブロックの先頭からのオフセット値。
|
■ Len : 割り当てた領域のサイズ |
|
フラッシュメモリをMS-FFSのフォーマットにしたがって初期化すると、各イレーズブロックは下図のような状態になります。
アドレス |
低 |
![]() |
BAS固定部 論理ブロック0 |
|
![]() |
BAS固定部 論理ブロック1 |
|
… |
![]() |
BAS固定部 スペアブロック
|
|
高 |
|
イレーズ ブロック0 |
イレーズ ブロック1 |
|
イレーズ ブロック15 |
|
この状態からイレーズブロックにデータを書き込んでいきます。
フラッシュファイルシステムでは、イレーズブロックにデータを書き込む場合はアドレスの低い方から高い方に向かってバイト単位でつめて配置していきます。
データを書き込むためには領域を割り当て、1つの管理単位とします。この領域を管理するために、BAS可変部である配列Allocの要素AS(以下、AS)を1つ生成します。場所はBAS固定部からアドレスの低い方に向って配置します。
この場合もバイト単位で行われます。この「バイト単位でつめて」というところからバイト指向方式と言われています。
例えば、33バイトのデータと25バイトのデータを順に書き込むと、下図のようになります。
|
 |
領域とそれに対応するASの関連は矢印のように関連付けられます。
これは上記BAS構造図のOffsetとLenの2つのフィールドの情報によって行われます。
あと、先に説明しておかなければならないものとして、
■ディレクトリエントリストラクチャ(Directory Entry Structure, DirEntry)
■ファイルエントリストラクチャ(File Entry Structure, FileEntry)
■ファイルインフォストラクチャ(File Info Structure, FileInfo)
の3つの構造体があります。それぞれ下図のような構造になっています。また、ファイルのデータそのものを置く領域のことをエクステント(Extent) といいます。
struct DirEntry {
wordStatus;
dword SiblingPtr;
dword PrimaryPtr;
dword SecondaryPtr;
byteAttributes;
wordTime;
wordDate;
wordVarStructureLen;
byteNameLen;
byteName[8];
byteExt[3];
}
|
struct FileEntry {
wordStatus;
dword SiblingPtr;
dword PrimaryPtr;
dword SecondaryPtr;
byteAttributes;
wordTime;
wordDate;
wordVarStructureLen;
byteNameLen;
byteName[8];
byteExt[3];
} |
struct FileInfo {
wordStatus;
dword ExtentPtr;
dword PrimaryPtr;
dword SecondaryPtr;
byteAttributes;
wordTime;
wordDate;
wordVarStructureLen;
wordUncompressedExtentLen;
wordCompressedExtentLen;
}
|
名前から分るようにそれぞれディレクトリ情報、ファイル情報、ファイルのデータの情報を管理する構造体となっています。これらの構造体のうち説明に必要なフィールドは
■ Status : エントリのステータス
|
エントリの状態を示す。
|
■ SiblingPtr : 次のエントリへのポインタ
|
同一階層に存在するDirEntryもしくはFileEntryへのポインタ。 |
■ PrimaryPtr : 次のエントリへのポインタ |
DirEntryの場合は子階層のDirEntry、FileEntryへのポインタ。FileEntryの場合はFileInfoへのポインタ。 |
■ SecondaryPtr : 次のエントリへのポインタ |
このエントリの最新版のエントリへのポインタ。 |
となっています。エントリのポインタは4バイトのサイズで、
上位2バイトが論理ブロック番号、下位2バイトがASのインデックスという構成になっています。
つまり、ポインタにはフラッシュメモリの物理アドレスは格納されないということです。
このようになっている理由はのちほど説明します。
ポインタの表記は便宜的に
論理ブロック番号 : ASのインデックス
というようにします。また、ヌルポインタを FNULL とします。
|
|