6.828: Operating System Engineering (8)
How Boot Loaders Work を読んでいるのですが、boot/sign.pl は無理矢理 512 にしてるだけではなくて、末端にマジックナンバー
The last two bytes of the sector are checked for the values 0x55 and 0xAA, this as a rough sanity check.
も入れてますね。
手順
として、
$buf に boot を読みこんで
read(BB, $buf, 1000);
length チェックした後に null をツメて
$buf .= "\0" x (510-$n);
ケツにマジックナンバーを入れてます。
$buf .= "\x55\xAA";
そしてこの $buf をファイルに出力してますね。
ざくっと読了
したので昨晩の続きをナニ。端末に昨晩の状態が表示されたママです。
(gdb) si [f000:e05b] 0xfe05b: jmp 0xfefdb 0x0000e05b in ?? () (gdb) si [f000:efdb] 0xfefdb: mov %cr0,%eax 0x0000efdb in ?? () (gdb) si [f000:efde] 0xfefde: and $0x9fffffff,%eax 0x0000efde in ?? () (gdb) si [f000:efe4] 0xfefe4: mov %eax,%cr0 0x0000efe4 in ?? () (gdb) si [f000:efe7] 0xfefe7: cli 0x0000efe7 in ?? () (gdb) si [f000:efe8] 0xfefe8: cld 0x0000efe8 in ?? () (gdb) si [f000:efe9] 0xfefe9: mov $0x8f,%eax 0x0000efe9 in ?? () (gdb) si [f000:efef] 0xfefef: out %al,$0x70 0x0000efef in ?? () (gdb) si [f000:eff1] 0xfeff1: in $0x71,%al 0x0000eff1 in ?? () (gdb) si [f000:eff3] 0xfeff3: cmp $0x0,%al 0x0000eff3 in ?? () (gdb)
0xfefdb に jmp して cr0 レジスタをナニしてますがマニュアルの記述によれば以下な模様。
CD フラグとNW フラグがクリアされると、プロセッサの内部(および外部)キャッシュにある物理メモリ全体のメモリ位置のキャッシングがイネーブルになる。
IA-32 インテル® アーキテクチャソフトウェア・デベロッパーズ・マニュアル 下巻より引用
で、割り込み disable にして DF フラグをクリアした後に
- 0x8f を IO ポートの 0x70 に出力?
- IO ポート 0x71 から入力?
なの? というのが昨晩の断点。http://web.archive.org/web/20040501054447/http://members.iweb.net.au/~pstorr/pcbook/book2/ioassign.htm:ココによれば 0070-0071 は NMI Enable / Real Time Clock とありますが、ちょっと何してるのか意味不明。
なので、ここのポインタから見てみたりしたのですが、どうも意味が分からん。
以下なスレッドを見つけたので中身を確認してみます。
とりあえず続きを進めてみます。
(gdb) si [f000:eff3] 0xfeff3: cmp $0x0,%al 0x0000eff3 in ?? () (gdb) si [f000:eff5] 0xfeff5: jne 0xff00a 0x0000eff5 in ?? () (gdb) si [f000:eff7] 0xfeff7: xor %ax,%ax 0x0000eff7 in ?? () (gdb) si [f000:eff9] 0xfeff9: mov %ax,%ss 0x0000eff9 in ?? () (gdb) si [f000:effb] 0xfeffb: mov $0x7000,%esp 0x0000effb in ?? () (gdb) si [f000:f001] 0xff001: pushl $0xf194b 0x0000f001 in ?? () (gdb) si [f000:f007] 0xff007: jmp 0xffeae 0x0000f007 in ?? () (gdb) si [f000:feae] 0xffeae: mov %eax,%ecx 0x0000feae in ?? () (gdb) si [f000:feb1] 0xffeb1: cli 0x0000feb1 in ?? () (gdb) si [f000:feb2] 0xffeb2: cld 0x0000feb2 in ?? () (gdb) si [f000:feb3] 0xffeb3: mov $0x8f,%eax 0x0000feb3 in ?? () (gdb) si [f000:feb9] 0xffeb9: out %al,$0x70 0x0000feb9 in ?? () (gdb) si [f000:febb] 0xffebb: in $0x71,%al 0x0000febb in ?? () (gdb) si [f000:febd] 0xffebd: in $0x92,%al 0x0000febd in ?? () (gdb) si [f000:febf] 0xffebf: or $0x2,%al 0x0000febf in ?? () (gdb) si [f000:fec1] 0xffec1: out %al,$0x92 0x0000fec1 in ?? () (gdb) si [f000:fec3] 0xffec3: lidtw %cs:0x7a18 0x0000fec3 in ?? () (gdb) si [f000:fec9] 0xffec9: lgdtw %cs:0x7a58 0x0000fec9 in ?? () (gdb) si [f000:fecf] 0xffecf: mov %cr0,%eax 0x0000fecf in ?? () gdb) si [f000:fed2] 0xffed2: or $0x1,%eax 0x0000fed2 in ?? () (gdb) si [f000:fed6] 0xffed6: mov %eax,%cr0 0x0000fed6 in ?? () (gdb) si [f000:fed9] 0xffed9: ljmpl $0x8,$0xffee1 0x0000fed9 in ?? () (gdb) si The target architecture is assumed to be i386 => 0xffee1: mov $0x10,%eax 0x000ffee1 in ?? () (gdb)
む、longjmp したな。それまでに cr0 のいっちゃん右のビットを立てたり NMI なソレについて同様の処理をしてたり 0x92 から読みこんで右から 2 番目のビットを立てたりしてますね。ええとhttp://web.archive.org/web/20040501054447/http://members.iweb.net.au/~pstorr/pcbook/book2/ioassign.htm:ココによれば、
0090-009F System devices
との事。謎だなぁ。と思ったらココの記述によれば A20 の enable/disable とのこと。A20 って明確に何なのか、を完全に忘れているので自分エントリを検索した後にうにまがを経て今に至っております。
昼だ
gdb はもう少しすすめてみる方向ですが、先の NMI なスレッドを確認してみます。