今度は、OS本体起動時に、ビデオモードを設定してみる。
tinyos.s
.text .code16 movb $0x00, %ah movb $0x13, %al int $0x10 fin: hlt jmp fin正しく実行できれば、真っ暗な画面が表示されるはず。
だが、試してみると動かない。
原因としては、次ののどちらか。
jmp 0xC200 で 0xC200にジャンプしていない。
FDからOS本体のイメージを正しく読んでいない。
前日に、jmp 0xC200 で実行したところ、正しく動作せず、
jmp *0xC200 にしたら、見掛け上は動いているようだったので
安心していたが、このコードでは、
0xC200に書いてあるアドレスにジャンプする命令だったようだ。
ソースとリンカスクリプトを再チェック、ビルド方法の確認をしてみたが、今のところお手上げ。
仕様がないので、qemu上のコードをGDBでデバッグすることにした。
Makefile に デバッグ用のターゲットを追加する。
Makefile
debug: qemu-system-i386 -m 32 -localtime -vga std -fda ${image_file} \ -gdb tcp::10000 \ -SGDBは、起動時に実行するスクリプトファイルを指定できる。
今後の開発で、多分、実行したいコマンドが増えると思うので、作成しておく。
gdb.scr
target remote localhost:10000make debug で qemuを起動した後に、gdbを-xオプションでスクリプトファイルを指定して起動する。
$ gdb -x gdb.scrブレークポイントを0x7c00に設定する。
(gdb) b *0x7c00 Breakpoint 5 at 0x7c00ブレークポイントまで実行する。
(gdb) c Continuing. Breakpoint 5, 0x00007c00 in ?? ()止まった。 ジャンプする直前で止めたいので、lstファイルを確認すると、該当箇所は0x00acなので、 0x7cacにブレークポイントを設定し、continueする。
80 // シリンダ 81 00a3 80C501 add $1, %ch 82 00a6 3A2E0A00 cmp MAX_CYLINDER, %ch 83 00aa 72B9 jb readloop # シリンダは 0 〜 MAX_CYLINDER - 1 84 00ac E90000 jmp 0xC200 # 0x8000 + 0x4200 = 0xC200 ← ◆ここ
(gdb) b *0x7cac Breakpoint 2 at 0x7cac (gdb) c Continuing. Breakpoint 2, 0x00007cac in ?? ()レジスタ値を確認する。
(gdb) i all-registers eax 0x840 2112 ecx 0x101 257 edx 0x0 0 ebx 0x0 0 esp 0x7c00 0x7c00 ebp 0x0 0x0 esi 0x0 0 edi 0x0 0 eip 0x7cac 0x7cac eflags 0x202 [ IF ] cs 0x0 0 ss 0x0 0 ds 0x0 0 es 0x840 2112 ← ◆これ fs 0x0 0 gs 0x0 0あれ?ESレジスタが1回分しか0x20が加算されておらず、0x840になっている。 停止させたアドレスが間違っているのかと思って、continueしたけど
(gdb) c Continuing.このまま止まらなかった。 イメージ読み込みがうまく動いていないのか。
ソースをチェックすることにしよう...
0 件のコメント:
コメントを投稿