0から作るOS開発 ブートローダその4 FAT12
0から作るソフトウェア開発

日々勉強中。。。

0から作るOS開発

環境準備

環境設定

ブートローダ

カーネルローダ

GRUB

カーネル

ドライバーその他

ブートローダその4 FAT12

前回までの内容

これまでで、 ということがわかりました。今回はフロッピーのファイルシステムであるFAT12の仕様について

FAT12ファイルシステムのさわり

フロッピーのファイルシステムはMicrosoftが開発したFAT(File Allocation Table)が主に使用されています

FATのなかでも特に容量が少ないディスクで使われるのがFAT12と呼ばれているものです

FAT12の仕様は決まっていて Microsoftのホームページ からダウンロードできます。興味のある方は

ダウンロードして見てみてください

仕様書を見てみると最初のほうに"Boot Sector and BPB Structure"の表があります

これがFAT12の最初のセクタに書くべきヘッダみたいなものとなります

"Boot Sector"はそのままブートセクタで最初のセクタの名前です(ここからはブートセクタと言います)

"BPB"は"BIOS Parameter Block"の略でそのディスクのセクタ数などを記録するものです

仕様で決まっていますので、このブートローダもその仕様に従って作っていこうと思います

(ついでにファイルシステムの勉強も兼ねて。。。)

FAT12のブートセクタ

FAT12のブートセクタは仕様によりますと、0バイト目から62バイト目を埋める必要があります

それではFAT12のブートセクタとBPBのデータ構造を見て行きましょう

下の表に記載されているオフセットというのは最初のデータの位置を0バイト目として0バイト目から数えて

何バイト目にあるかという意味になります

FAT12のブートセクタとBPB
ラベル名 オフセット
(バイト)
サイズ
(バイト)
説明
BS_jmpBoot 0 3 ブートローダの実行プログラムにジャンプします。例えばブートローダの最初の命令がBoot:ラベルにあればそのアドレスを書いて置きます。 そうするとBoot:ラベルまでジャンプしてくれます。仕様書ではjmpBoot[0]=0xEB, jmpBoot[1]=0x??, jmpBoot[2] = 0x90 にしろと書いております。0xEBはジャンプ命令のコードで0x??はそこから何バイトジャンプするかで0x90は特に意味はありません。 (特に0x90でなくてもよいみたいです) ここはジャンプ命令+ラベルにしておけば、アセンブラが勝手にこのコードに変換してくれます。
※Windows8以降はjmpBoot[2]が0x90でないとフロッピーディスクと認識しなくなりました
BS_OEMName 3 8 OEM名を入れます。アスキーコードで8バイト入れてください。仕様では"MSWIN4.1"を推奨しています。
BPB_BytsPerSec 11 2 1セクタに何バイトあるかを入れます。フロッピーは1セクタ=512バイトでした。
BPB_SecPerClus 13 1 クラスタ(カーネルのロードで後々説明をします)に使用しているセクタ数を書きます。2の乗数を入れます。フロッピーでは1です。
BPB_RsvdSecCnt 14 2 予約領域で使うセクタ数を0以外で入れます。予約領域はブートセクタなのでフロッピーの場合は1です。
BPB_NumFATs 16 1 FAT(File Allocation Table)の数を入れます。フロッピーの場合は2です。
BPB_RootEntCnt 17 2 ルートディレクトリ(WindowsではAドライブの直ぐ下のフォルダです)が何バイト目に格納されているかを入れます。 フロッピーでは0xE0(224)バイト目となります。
BPB_TotSec16 19 2 そのメディアのセクタ総数を入れます。フロッピーは1.44MBありますので1474560バイト/512バイトパーセクタ=2880(0xB40) セクタとなります。
BPB_Media 21 1 メディアの種類を入れます。フロッピーはリムーバルメディアなので0xF0を入れます。
BPB_FATSz16 22 2 1つのFATに何セクタ必要か入れます。フロッピーの場合は9セクタとなります。
BPB_SecPerTrk 24 2 1トラックにつき何セクタあるかを入れます。フロッピーの場合は0x12(18)セクタです。
BPB_NumHeads 26 2 ヘッドの数を入れます。フロッピーはディスクが1枚で両面読み書きできますので2になります。
BPB_HiddSec 28 4 見えないセクタ数を入れます。例えばパーティションを区切っている場合などに使用します。 そのような複雑なことは普通しないのでここには0を入れておきます。
BPB_TotSec32 32 4 FAT32のときの総セクタ数を入れます。フロッピーはFAT12なので0を入れます。
BS_DrvNum 36 1 BIOSの0x13ソフトウェア割り込み(後々説明します)で利用するドライブ番号を入れます。フロッピーの場合は0を入れます。
BS_Reserved1 37 1 予約領域です。0を入れておきます。
BS_BootSig 38 1 拡張ブートセクタシグネチャです。下の3つのフィールドBS_VolIDとBS_VolLabとBS_FilSysTypeが あるときに使います。普通は使いますので0x29を入れます。
BS_VolID 39 4 ボリュームシリアル番号を入れます。
BS_VolLab 43 11 ボリュームラベルを入れます。
BS_FilSysType 54 8 FATのタイプを入れます。フロッピーはFAT12なので"FAT12 "です。(空白に注意してください)

FA12のブートセクタを作ってみる

では早速FAT12のブートセクタを作ってみましょう。

;/********************************************************************************
; File:boot.asm
; Description:Bootloader
;
;********************************************************************************/
[BITS 16]

ORG	0x7C00

;==================================================================================
; BIOS parameter blocks(FAT12)
;==================================================================================
JMP	BOOT		;BS_jmpBoot
BS_jmpBoot2	DB	0x90
BS_OEMName	DB	"MyOS    "
BPB_BytsPerSec	DW	0x0200		;BytesPerSector
BPB_SecPerClus	DB	0x01		;SectorPerCluster
BPB_RsvdSecCnt	DW	0x0001		;ReservedSectors
BPB_NumFATs	DB	0x02		;TotalFATs
BPB_RootEntCnt	DW	0x00E0		;MaxRootEntries
BPB_TotSec16	DW	0x0B40		;TotalSectors
BPB_Media	DB	0xF0		;MediaDescriptor
BPB_FATSz16	DW	0x0009		;SectorsPerFAT
BPB_SecPerTrk	DW	0x0012		;SectorsPerTrack
BPB_NumHeads	DW	0x0002		;NumHeads
BPB_HiddSec	DD	0x00000000	;HiddenSector
BPB_TotSec32	DD	0x00000000	;TotalSectors

BS_DrvNum	DB	0x00		;DriveNumber
BS_Reserved1	DB	0x00		;Reserved
BS_BootSig	DB	0x29		;BootSignature
BS_VolID	DD	0x20120627	;VolumeSerialNumber 日付を入れました
BS_VolLab	DB	"MyOS       "	;VolumeLabel
BS_FilSysType	DB	"FAT12   "	;FileSystemType

;/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;
; BOOT
;
;/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
BOOT:
	CLI
	HLT
	
TIMES 510 - ($ - $$) DB 0

DW 0xAA55


変数の宣言がいくつか出てきました


BS_OEMName	DB	"MyOS    "

前回でてきましたDBと同じ宣言です。しかし、今回は前に”BS_OEMName”が付いています

これはやはりラベルと言います。ラベルは変数名だと思っていただければと思います

(ただしラベルは場所を示しているのでアセンブルするとアドレスに変換されます)

後ろの""で囲んだものは文字列としてここに配置されます

このDBはC言語のchar*型のようなイメージと言えばわかりやすいでしょうか。。。

この場所から文字数分アスキーで配置されます


BPB_BytsPerSec	DW	0x0200


DWはワードサイズのデータを宣言します。ワードとはC言語のint型のような感じです

IntelのCPUの場合16ビットのワードは2バイトとなります


BPB_TotSec32	DD	0x00000000


DDはダブルワードのデータを宣言します。ダブルワードはその文字のごとくワード×2となります

IntelのCPUで16ビットのダブルワードは4バイトとなります



では前回と同様アセンブルしてVirtual Boxで動かしてみてください。見た目は全然かわりませんが。。。

これでFAT12のブートセクタのヘッダができました!

inserted by FC2 system