「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。
目的
将来BIOSを開発するにあたり、INT 13H(ディスク読み込み)も自分で実装する必要があります。
データを読み込む対象の装置によって接続方法が異なるので、自分の普段動作確認に使っているQEMUがフロッピー起動扱いなのかHDD起動扱いなのかを検証します。
せっかくなので8086実機でも動かしてみます。
筆者の所有している8086実機はチップだけ当時のものでそれ以外は新しい部品を使用して生産されたものです。(復刻機)
CF(コンパクトフラッシュ)から起動していて実際にはフロッピーもHDDも接続されていません。
良い機会なのでどちらの扱いになっているかを確認します。
検証コード
IDEコントローラの状態レジスタ(ポート:0x1F7)から応答があればHDD、なければフロッピーと判断する簡易的な判別です。
起動ディスク以外には何も繋いでいないのでこれで足りるでしょう。
bits 16
org 0x7C00
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
; TXTモードを明示的に設定して間接的に画面クリア
mov ax, 0x0003
int 0x10
; 起動装置判別
call detect_boot_device
; 結果を表示
cmp byte [boot_device], 0
je .floppy
cmp byte [boot_device], 1
je .harddisk
jmp .unknown
.floppy:
mov si, floppy_msg
jmp .print_msg
.harddisk:
mov si, hd_msg
jmp .print_msg
.unknown:
mov si, unknown_msg
.print_msg:
call print_string
jmp $
; 起動装置判別
; 出力: [boot_device] = 0 (FDD) 或 1 (HDD)
detect_boot_device:
; ポートから読み取った値が 0xFF(全ビット1)
; であれば応答はなくHDDは接続されていないと判断
mov dx, 0x1F7 ; IDEコントローラの状態レジスタ
in al, dx
cmp al, 0xFF
je .likely_floppy
; HDD
mov byte [boot_device], 0
ret
; FDD
.likely_floppy:
mov byte [boot_device], 1
ret
print_string:
lodsb
or al, al
jz .done
mov ah, 0x0E
int 0x10
jmp print_string
.done:
ret
boot_device db 0
floppy_msg db "Booted from floppy disk", 0x0D, 0x0A, 0
hd_msg db "Booted from hard disk", 0x0D, 0x0A, 0
unknown_msg db "Booted from unknown device", 0x0D, 0x0A, 0
times 510-($-$$) db 0
dw 0xAA55
動作確認
QEMU
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
8086実機
sudo dd if=boot.bin of=/dev/sdc bs=512 count=1 conv=notrunc
MSIゲーミングノート(MS-16R4)
BIOSの設定をUEFIからLegacyBIOSへ変更し現代のパソコンでも試してみました。
未知の機器のようです。現代は仕様が全然違う?
間違い訂正(当日)
そもそもQEMUを立ち上げる時に-fdaオプションをつけてフロッピー扱いにしていました。
かなり前に書いたコマンドを何も考えずに使いまわしており気づきませんでした。
qemu-system-i386 -hda boot.bin
画面クリアを消すと、QEMUはHDDから立ち上げているのに判別がおかしくHDDとして判定されていました。
どこで間違えたのか分からない為後日検証し直します。