0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MBR・VBR自作でFAT16として認識させる

Posted at

「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。

MBR VBRとは

通常、HDDなどの記憶媒体では先頭の512バイトに**MBR(Master Boot Record)が存在します。FATファイルシステムで初期化されたパーティションの先頭にはVBR(Volume Boot Record)**が置かれます。
MBR中でパーティションが4つまで登録でき、それにより一つのHDDをCドライブ、Dドライブと分割できます。
そしてそれぞれのパーティションの先頭の512バイトにはVBRと呼ばれるデータが置かれ、ここにはFATに関する情報が記録されます。
OSが起動可能なHDDの場合は初めにMBRを実行し、その後VBRを実行し、その後カーネルと順を追って実行されます。
ファイルシステムを実装していないOS自作本ではいきなりMBRからOSのコードを立ち上げていることもありますが、FAT16でファイルシステムを実装する場合は以下の用に実装できます。

MBRのコード

[BITS 16]
[ORG 0x7C00]

start:
    ; 1. MBRを安全な領域(0x0600)へ退避
    xor ax, ax
    mov ds, ax
    mov si, 0x7C00
    mov di, 0x0600
    mov cx, 512
    rep movsb

    ; 2. セグメントレジスタの初期化
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00
    
    ; 0x0600にジャンプして処理を続行
    jmp 0x0000:(continue - start + 0x0600)

continue:

    mov si, msg_loading
    call print_string

    ; 4. VBRを0x7C00に読み込む(このコードを上書き)
    mov ah, 0x02
    mov al, 1       ; 読み込むセクタ数
    mov ch, 0       ; シリンダ番号
    mov cl, 1       ; セクタ番号(1〜63)
    mov dh, 1       ; ヘッド番号
    mov dl, 0x80    ; 一台目のHDDを読み込む
    mov bx, 0x7C00
    int 0x13
    jc disk_error

    ; 5. 0x7C00に読み込んだVBRへ跳ぶ
    jmp 0x0000:0x7C00

print_string:
    lodsb
    or al, al
    jz .done
    mov ah, 0x0E
    int 0x10
    jmp print_string
.done:
    ret

disk_error:
    mov si, msg_disk_error
    call print_string
    jmp $

msg_loading db "Loading VBR...", 0
msg_disk_error db "Disk read error!", 0

; MBRの残りを埋める
times 446-($-$$) db 0

; パーティションテーブル(FAT16のパーティション)
db 0x80               ; アクティブパーティション
db 0x01, 0x01, 0x00   ; CHS開始位置(0,1,1)
db 0x04               ; パーティションタイプ(FAT16)
db 0xFF, 0xFF, 0xFF   ; CHS終了位置(最大値)
dd 63                 ; 開始LBA(63セクタ目)
dd 4096               ; セクタ数(約2MB)

; 残りの3つの空パーティションを埋める
times 16 * 3 db 0

dw 0xAA55

VBRのコード

[BITS 16]
[ORG 0x7C00]  ; VBRはアドレス0x7C00に読み込まれる

; FAT16のBPB
jmp start
nop
db "MSWIN4.1"     ; OEM名
dw 512           ; セクタあたりのバイト数
db 1             ; クラスタあたりのセクタ数
dw 1             ; 予約セクタ数
db 2             ; FATテーブルの数
dw 512           ; ルートディレクトリ項目数
dw 4096          ; 総セクタ数(16ビット)
db 0xF8          ; 媒体種別(HDD等)
dw 8             ; 各FATのセクタ数
dw 63            ; トラックあたりのセクタ数
dw 255           ; ヘッド数
dd 63            ; 隠しセクタ数
dd 0             ; 総セクタ数(32ビット、16ビットが0の場合に使用)
db 0x80          ; BIOSドライブ番号(0x80=HDD)
db 0             ; 予約(使用されない)
db 0x29          ; 拡張ブート用
dd 0x12345678    ; ボリューム番号
db "FAT16DISK "  ; ボリュームラベル
db "FAT16   "    ; ファイルシステムの種類

start:

    mov si, msg_loaded
    call print_string

    ; FAT16ファイルシステムのマウント(今後の拡張用)
    jmp $       ; 無限ループ(実際にはファイルシステムを読み込む)

print_string:
    lodsb
    or al, al
    jz .done
    mov ah, 0x0E
    int 0x10
    jmp print_string
.done:
    ret

msg_loaded db "FAT16 VBR Loaded!", 0

; 残りの領域を512バイトまで埋める
times 510-($-$$) db 0

dw 0xAA55

起動

OSはまだ実装していませんがMBRからVBRを起動することに成功しました。

# コンパイル
nasm -f bin mbr.asm -o mbr.bin
nasm -f bin vbr.asm -o vbr.bin

dd if=/dev/zero of=virtual_disk.img bs=1M count=1024  # 1GBの仮想HDD生成

# MBRを先頭512バイトへ書き込み
dd if=mbr.bin of=virtual_disk.img bs=512 count=1 conv=notrunc

# VBRを63セクタ目へ書き込み「第1パーティションの先頭512バイト」
dd if=vbr.bin of=virtual_disk.img bs=512 seek=63 conv=notrunc

# 起動する
qemu-system-i386 -hda virtual_disk.img

图片.png

仮想HDDが本当にFATとして識別されるかをXPで検証

先ほど作った仮想HDDをWindowsXPでEドライブとして読み込ませるとFATとして認識されました。

  qemu-system-i386 \
  -m 1024 \
  -hda xp.img \
  -hdb virtual_disk.img \
  -boot c \
  -cpu host \
  -smp 2 \
  -net nic -net user \
  -vga std \
  -rtc base=localtime \
  -enable-kvm \
  -usbdevice tablet

图片.png

次回

次はNASMを用いて実際に簡単なファイルを書き込み、XP上で読み込まれるかを確認します。
又、今回はOSを起動するHDDのMBRとVBRを自分で研究してコードを書きました。
OSの入っていないただのHDDの場合にもMBRとVBRは生成されるようなので、実際にXPで初期化をしてどんなデータが生成されるのかを見てみます。
恐らく実行できる命令はないのではないかと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?