「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。
目的
昨日正常に動かずハマった原因がスタックとは関係がなかったようなので、その原因を記録する
昨日正常に動かなかったコード
load.asm
[org 0x7E00]
[bits 16]
;********************************************************************************
; システム初期化ブロック
;********************************************************************************
start:
; === セグメントレジスタ初期化 スタック設定===
cli
xor ax, ax
mov ds, ax ; データセグメントは 0 にしておく(test_string などの参照に対応)
mov es, ax
mov si, 0x7E00
mov ax, 0x9000 ; 安全な場所にスタックを置く(0x9000:FFFF = 0x9FFFF)
mov ss, ax
mov sp, 0xFFFE ; FFFEが望ましい(偶数)
sti
mov si, test_string
call print_str
mov si, hlt_msg
call print_str
cli
.loop:
hlt
jmp .loop
print_str:
push ax
push si
mov ah, 0x0E ; BIOSテレタイプ機能
.loop:
lodsb ; 次の文字をALにロード
test al, al ; ヌル文字チェック
jz .done
int 0x10 ; BIOS文字表示
jmp .loop
.done:
pop si
pop ax
ret
halt:
cli
.loop:
hlt
jmp .loop
test_string db 'TEST',0x0D,0x0A,0
hlt_msg db 'HALT',0x0D,0x0A,0
DAMMY db 'DAMMY',0x0D,0x0A,0
; 0埋め(512バイト×3のコードサイズを保証)
times 512 * 3-($-$$) db 0
昨日上手く表示されなかった例
clear
nasm -f bin boot.asm -o boot.bin
nasm -f bin load.asm -o load.bin
rm testdisk.img
dd if=/dev/zero of=testdisk.img bs=512 count=2880
mkdosfs -F 12 -v testdisk.img
# 第1セクタにブートローダーを書き込み
dd if=boot.bin of=testdisk.img bs=512 seek=0 count=1 conv=notrunc
# 第2〜4セクタに拡張ローダーを書き込み
dd if=load.bin of=testdisk.img bs=512 seek=1 count=3 conv=notrunc
rm boot.bin
rm load.bin
#sudo mkdir /mnt/floppy
# マウント
sudo mount -o loop,fat=12 testdisk.img /mnt/floppy
# ファイル書き込み
echo "Hello FAT12!" | sudo tee /mnt/floppy/test.txt
echo 'Hello FAT12!aaaaa' | sudo tee /mnt/floppy/test2.txt #2komeha singuru
sudo mkdir /mnt/floppy/TEST_DIR
# 書き込み結果確認
ls -l /mnt/floppy
# アンマウント
sudo umount /mnt/floppy
qemu-system-i386 -fda testdisk.img
今日うまく行った動作手順
ファイル書き込みをやめ、この手順で動作させると正常に動作した
clear
nasm -f bin boot.asm -o boot.bin
nasm -f bin load.asm -o load.bin
rm testdisk.img
dd if=/dev/zero of=testdisk.img bs=512 count=2880
mkdosfs -F 12 -v testdisk.img
# 第1セクタにブートローダーを書き込み
dd if=boot.bin of=testdisk.img bs=512 seek=0 count=1 conv=notrunc
# 第2〜4セクタに拡張ローダーを書き込み
dd if=load.bin of=testdisk.img bs=512 seek=1 count=3 conv=notrunc
# rm boot.bin
# rm load.bin
qemu-system-i386 -fda testdisk.img
バイナリ比較
以下の手順で、動かない場合と動く場合とのイメージをバイナリ比較する。
dd if=testdisk.img bs=512 count=4 of=ugokanai.bin
dd if=testdisk.img bs=512 count=4 of=ugoku.bin
diff <(xxd ugokanai.bin) <(xxd ugoku.bin)
その結果は以下。
大きな問題が2つあることが分かった。
文字列のあとの終端文字(0)がf0ff ff0fに置き換わっている。これでは終端を判別できずに次の文字列まで表示しようとしてしまう。
改行の0d0aが0dfaに代わっている。
ubuntu@ubuntu:~/kaihatsu/test3$
diff <(xxd ugokanai.bin) <(xxd ugoku.bin)
37c37
< 00000240: 4c54 0dfa ff44 414d 4d59 0d0a f0ff ff0f LT...DAMMY......
---
> 00000240: 4c54 0d0a 0044 414d 4d59 0d0a 0000 0000 LT...DAMMY......
考察
はっきりとした原因は分からないが動作確認用のファイルを書き込んだ時にプログラムの領域が破壊されている。
これから調べていく。
余談
筆者は中国で働いており、今週は端午の節句で三連休でした。
南京の方へ遊びにでも行こうかと思っていたのですが、結局バグの調査に3日間使ってしまいました。
有料の自習室で作業することが多いです。風景を貼ります。