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 なスレッドを確認してみます。