FAT12ファイルシステムを読み込む前回までの内容これまでで、フロッピーディスクからデータを読み込むにはINT0x13命令を使うINT0x13命令にはフロッピードライブ初期化モードとセクタ読み込みモードがあるフロッピードライブ初期化モードを使うには引数としてAHレジスタに0x00を入れて使う初期化するとヘッドが最初のセクタの位置まで移動するセクタ読み込みモードは引数としてAHレジスタにx002を入れて使う読みたいセクタ数(AL)、シリンダ(CH)、セクタ番号(CL)、ヘッド番号(DH)、格納するアドレス(ES:BX)を指定するINT0x13命令の両方のモードの返り値としてEFLAGSレジスタのCFに成功:0、失敗:1が格納される読みたいセクタを指定するときは、ソフトウェア上ではLBAとして論理セクタでアクセスするLBAを物理ヘッダ番号、シリンダ番号、セクタ番号に変換してからINT0x13命令するということがわかりました。FAT12のさわりの部分で紹介しました。今回はFAT12の全体像(といってもブートローダで必要なところだけです。)を見ていきたと思います。このブートローダではフロッピーディスクと使用していますので、フロッピーディスク上でのFAT12を見ていきますFAT12の構造FAT12に大まかに分けて次のような領域に分かれていますブートセクタ:言わずもがなです。今作っているプログラムが入りますFAT領域:名前の由来です。Tableの省略です名前の通り、ファイルの情報が書かれていますルートディレクトリ領域:Aドライブの直ぐ下のフォルダーをルートディレクトリといいますファイル名などの情報が書かれていますファイル領域:ファイルが実際に格納されている領域ですFAT12として上記の4つの領域があります。実際にディスク上にどのように配置されている(どのような構造)のでしょうか?フロッピーディスクは全部で2880セクタありました(LBAで2880論理セクタです。今回の説明でも全てセクタは論理セクタとしています)この2880セクタはFAT12では下記図のような構造になっています(少なくとも今回使うFAT12では。Tableの省略でした。英語を日本語にしてみると、”ファイル割り当てテーブル”といったところでしょうかただのテーブルです。FATにはファイルがどのセクタに記録されている(割り当てられている)のかが書かれています。この”どのセクタに記録されているのか”という情報が書かれたものをクラスタといいますクラスタクラスタとは日本語でいうところの自然に集まったグループといえばいいのでしょうかファイルは当然512バイト以上あるものもありますそのような場合、ディスク上では何セクタかにまたがって記録されます(連続したセクタでない場合もあります)このようにそのファイルが記録されたセクタをファイル単位でグループ化したものがセクタになりますなにやらよくわかりませんが、とりあえずファイルがどのセクタに記録されているのかがクラスタに記録されていますではクラスタがFAT領域にどのように記録されているのか見てみますクラスタは図のように12ビットで1つのクラスタになります。FAT領域の最初にあるクラスタを0番目として数えますさきほどクラスタにはどのセクタに記録されているかが記録されていると書いておりましたが、正確には”クラスタ番号”が書かれています。このクラスタ番号から記録されているセクタ番号を計算しますクラスタの1つが1つのセクタに対応していて、例えばクラスタ番号2は33番目のセクタにあたりますこの計算の仕方は後述しますので、先にクラスタ番号の役割について見ていきますクラスタ番号の役割クラスタに書かれているクラスタ番号には次のクラスタの番号を入れますこうすることでそのファイルを記録されるのに使われている分の、クラスタ(セクタ)番号を知ることができます例えばクラスタ番号2からクラスタ番号8までの7つのクラスタ分のファイルは次のようにFATに記録されますこのファイルではクラスタ番号2から始まるのでクラスタ2の値を見てみると0x003と書かれていますこの値が次に続くクラスタ番号です。0x003と書かれていたので次にクラスタ3を見てみると0x004と書かれています。次にクラスタ4の値を見ていきますこのように次々と読み込んで行くと最後にクラスタ8の0xFFFにぶち当たりますこの0xFFFという値がこのファイルの終わりを意味していますこれでクラスタ番号2から始まるファイルはクラスタ2、3、4、5、6、7、8に記録されていることがわかります(ファイルサイズは7クラスタ×512バイト=3584バイトになります)このようにクラスタにはファイルを構成するクラスタ番号をチェインしていきますが、中には特殊なクラスタもあります特殊なクラスタ先ほどの例ででてきました特殊なクラスタとして0xFFFの値を持ち、終端を意味するクラスタがありました終端を意味するクラスタ番号としてFATの仕様書では0xFF8〜0xFFFを終端番号としていますその他にもFATの一番最初の2つも特殊なクラスタになります0番目のクラスタ0はFAT12では”FAT12”であることを意味する0xFF0が書かれます厳密にはBPB_Mediaの値+0xF00が入ります。今回はブートローダを作るときに、BPB_Mediaの値を0xF0としました。0xFF0がクラスタ0にはいります(仕様書での例を見ますと0xFF8が例として挙げられていますが、ここでは0xFF0としましたBPB_Mediaが0xF8だとリムーバルじゃないメディアの意味となります)また1番目のクラスタ1は終端番号0xFFFが入りますまたその他に、0xFF7という値が入っていればそのクラスタ(セクタ)は不良セクタという意味になりますそしてファイルに割り当てがないクラスタは0x000が入ります。ファイルを削除した場合に、OSはファイル領域のデータは消さずに、FAT領域のクラスタ情報を0x000にします(ファイルを参照できなくなっただけで、ファイル自体のデータは残っています)FATで記録できるファイルFAT領域は全部で9セクタあります(もちろんフロッピーディスクでの話です)そのサイズは9セクタ×512バイト=4608バイトになります最初に2つのクラスタは上記で見た通り特殊なクラスタですので、その分を引くと4608バイト-3バイト(クラスタ2つ分)=4605バイトとなりますそして4605バイトに記録できるクラスタの数は4605バイト÷1.5バイト(クラスタ1つは12ビット)=3070個のクラスタをFATの中に入れることができますので、FAT12で作れるファイルは最大3070個となりますまた、FAT12のファイルの最大サイズは3070クラスタ×512バイト=1571840(約1.5M)バイトとなりますここまで見てきましたように、FATはファイルの位置やサイズを記録している重要な領域ですので、予備としてもう一つありますFATの予備FAT領域には2つのFATがあります。予約領域のサイズ(予約領域のセクタ数)を足せばFAT領域の開始セクタが得られますでは次にFAT領域を読み込むセクタ数(FAT領域のサイズ)を計算しますFAT領域のサイズFAT領域のサイズもパラメータから得られます(計算の必要はありません。ここからエラー発生時の処理。ドライブ番号このソースではFAT領域を0x7E00に読み込む処理をしていますもう少し具体的にはFATの開始セクタを取得FAT領域のサイズを計算(FAT領域の予備も念のため読み込む)FAT領域のサイズ分1セクタずつ読み込む1セクタ読み込み終わると格納アドレスに1セクタ分のバイト数を足すセクタの読み込みに1セクタずつやっているので効率が悪い例です。効率よい処理に直してみることをおすすめしますReadSector関数は前回の内容からパワーアップさせてますセクタ読み込みでエラーがあったかどうか判断して、エラーがあればドライブ初期化しています。0x0004と読み取れますこれでクラスタの値が読み取れるようになりましたクラスタ番号を読取るアセンブラコードを見てみましょう次のソースコードは少し後の説明にでてくるファイルの読み込みのLOAD_IMAGEラベルで使用するソースコードの一部です(ファイルの読み込みではNEW_CLUSTERラベルからLOAD_IMAGEラベルに変更しています)。最初のMOV命令ではファイルの先頭のクラスター番号をclusterに格納しています。NEW_CLUSTERではクラスターのチェインをファイルの終端に達するまでたどっていきます。読み取ったクラスタの値をclusterへ格納。BPB_SecPerClusクラスタ番号から2を引いていますが、FAT領域の最初の2つ(0番目と1番目のクラスタ)は特殊なクラスタでしたので、この2つ分を取り除いているからですそして1クラスタごとのセクタ数はブートセクタのBPB_SecPerClusの値となりますただし、注意していただきたい点があり、このファイルのセクタ番号はファイル領域先頭を0番目としたオフセットとなります(一番最初のブートセクタからのセクタ番号ではないことに注意です)アセンブラも一応見ておきましょう次のソースコードも少し後の説明にでてくるファイルの読み込みのLOAD_IMAGEラベルで使用するソースコードの一部です(先ほどのNEW_CLUSTERラベルの処理の前段階の処理となります)。番号がclusterに格納されているものとして、処理を行います。cluserに格納されているクラスター番号から最終的にファイルのセクター番号を計算してその結果をAXレジスターに格納する処理となります。MUL命令でAXの値とCXの値をかけます。結果はAXレジスタに格納されます上記でAXレジスタにクラスタ番号を変換したファイルのセクタ番号が格納されますFAT領域まとめこれまでで、FATの開始セクタ、サイズを取得FAT領域を読み込む読み込みたいクラスタ番号を指定してクラスタの値を読んでいく読んだクラスタ番号からファイルのセクタ番号(オフセット)を計算ができるようになりましたでは次にルートディレクトリ領域を見ていきますルートディレクトリ領域ルートディレクトリにはファイルの情報が書かれています中でも重要なのがファイル名とそのファイルの開始クラスタですブートローダがファイルをロードする場合にはまずこのルートディレクトリにあるカーネルの”ファイル名”を探します。ファイルが見つかった場合、そのファイルの開始クラスタを見ます。開始クラスタが分かったので、FAT領域にあるクラスタを見に行きます。