Personal tools
You are here: Home ブログ 学習経過 ブートローダー(その5)
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
sysfs tips 02 ohyama 2010-09-09
sysfs tips ohyama 2010-09-02
Haskell で周波数スペクトルを得る ohyama 2010-07-29
Haskell で線形識別関数の学習を行う ohyama 2010-07-19
Haskell で逆行列を求める ohyama 2010-07-16
Recent comments
Re:vim に lisp 機能をつける t.mimori 2010-12-16
Re:Haskell で周波数スペクトルを得る H.OHYAMA 2010-08-01
Re:lkml でお勉強 (その1-1) Hiroyasu OHYAMA 2009-08-21
Re:lkml でお勉強 (その1-1) kosaki 2009-08-20
Re:vim に lisp 機能をつける ohyama 2008-05-08
Categories
学習経過
GNU/Linux
 
Document Actions

ブートローダー(その5)

前回までで、ブートパラメータの初期化を完了した。
今回も、start_of_setup を前回の続きから解説しながら読んでゆく。

ソースではまず、割り込み信号を無視して、0x70 番I/Oポートに0x80を送っている。
ここでの目的は、NMIによる割り込みを発生させないようにしている。CLIによってINTRに送られる割り込み信号は無視されるが、NMIによる割り込みは無視できない。そこで、割り込み信号を送信して来ないように、0x0070の最上位ビットを立てる事でNMIの送信を停止させている。
これは、プロテクトモードに移行した直後において、割り込みハンドラが正常に呼び出されない可能性がある為に、NMIを発生させないようにしている(しかし、nmi_watchdog ブートパラメータを指定した覚えは無いぞ!?)。

次に、以前に初期化したブートパラメータを 0x100 をベースセグメントとする領域に4KBの転送を行う。これは、以前に少しだけ話しをした旧式のカーネルを扱っている場合、この処理は飛ばされる。

そして、A20 ラインを有効にする処理を行う。
その前に、本当にA20ラインが無効になっているかどうかを確かめる。a20_test でこれを行っている。
何だかややこしい事をやっているが、やっている処理は簡単である。詳細に見てゆく。

まず、0x0000 を %fs セグメントレジスタに格納し、 0xFFFF(-1(10)*) を %gs セグメントレジスタに格納している。
そして、%fs をベースセグメントとする適当なアドレス(A20_TEST_ADDR: 8*0x80)に格納されている値を %ax レジスタに一旦コピーし、incw %ax を実行した後、再び %fs:(A20_TEST_ADDR) に格納し、%ax と %gs:(A20_TEST_ADDR+0x10) を比較している。
もし、A20アドレスバスが無効である場合、%fs:(A20_TEST_ADDR) と %gs:(A20_TEST_ADDR+0x10)は同じアドレスを指す。又、A20 アドレスバスが有効であるならば、 は全く別のアドレスを表している為、(多分)比較に失敗する。

(*)10進数における -1 を表している(0x0000 を %cx レジスタに格納し、decw を実行し、movw %cx, %gs を実行している。負数を 2 の補数で表した時、%gs の値は、0xFFFF になる)。

ここで考慮しなければならないのは、A20が有効になっている場合に最後の比較演算の結果が 0 となる場合である。つまり、両者の別々のアドレスに同一の値が偶然含まれている場合である。
この為に loopz を実行し、複数回(1024回) %ax をインクリメントし比較する処理を行い、誤審を防いでいる(2,3回のループで済むのではないだろうか)。
これにより、A20 が無効であると判断されると、a20_bios に処理が移る。

ここでようやく、A20 を有効にする。
以前にも言ったとおり、A20アドレスラインの制御はキーボードコントローラが行っている。以前の文章では、デバイスコントローラに対して直接 I/O を出していると言ったが、setup.S ではまず BIOS によるA20アドレスラインの有効化が行われている。
システムが PS/2 以降であるならば、INT 15 (function 2401) を実行し、A20 アドレスラインを有効化する。そして、再び a20_test へ処理を移し、A20 アドレスラインが有効になっていると判定された場合、A20 の一連の処理を終了する。

これまでの処理でも多く見られてたが、setup.S では、(たぶん、大人の事情により)多くの下位互換が保たれている。ここでもそうだ、PS/2以降の機種であるならば後の、煩瑣な有効化処理を飛ばす。これらの「汎用的」なソースのおかげでコードの量が膨らんでいるが、それでも 1000 行そこそこ(setup.S 限定)。
だが、自分の環境に沿った必要な処理に実装を限定した場合、もっと簡潔なソースとなる事だろう。

まだ、プロテクトモードに移行させるまでにやらなければならない事がある。IDTの初期化処理だ。
つづきはまた今度。

Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/30fc30c830ed30fc30fc-305d306e5/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.