Personal tools
You are here: Home ブログ 学習経過 ブートローダー(その4)
« 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

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

前回、start_of_setup 関数の中身を読みはじめ、リアルモードにおける拡張メモリ領域のチェックと、e820map 構造体の初期化及びブートパラメータの設定まで見てきた。
今回はその続きを見てゆく。

まず、キーボードのリピート/ディレイの設定を行っている。
そもそも、何故キーボードからの割り込みが発生した時にディレイ(遅延)を設けるのかというと、ディレイ時間が極端に小さい場合、キーを押下した時一瞬で画面がキーで埋め尽くされ、CPU処理時間の大半をI/Oに持っていかれてしまう為だ(と思う)。
これが設定されると、最初にキーが押下されてからディレイ時間が経過するまで、(BIOSがどのレイヤでこれを制御しているのか不明だが)キー入力の受け付けを行わない。又、キーが押され続けた時、リピートで設定した間隔で繰り返してI/Oが発行される。
ここでは、ディレイ時間が 250ms、リピート間隔が 30字/sec に設定されている。

そして、ビデオアダプタのチェックと、0x00 ブートパラメータの設定を video 関数(video.S) で行っている。
このパラメータ情報は、screen_info 構造体に格納され、SCREEN_INFO マクロがこのブートパラメータのアドレスを持つ。

次に、BIOS 予約領域 0x0000:0x0104 から 0x9000:0x0060 に対して16バイト分のデータを転送している。ここでは、プライマリHDD のパラメータを設定している。次に、同様にしてセカンダリHDDのブートパラメータを設定している。そして、セカンダリHDDのディスクナンバーを %dl レジスタに格納し、INT 13 (function 0x15) を呼び出し、ディスクタイプを取得する。
これに失敗もしくは、ディスクタイプがHDDではない場合、0x90 ブートパラメータをクリアする。

この後に、ROMテーブルのブートパラメータの設定を行っている。ROMテーブルには、その名の通り、BIOSの情報が格納される。
まず、ROMテーブルを格納するブートパラメータ 0xc0 を 0 で初期化し、INT 15 (function 0xc0) を呼び出し、ES:BX が指すアドレスに最大19バイトのROMテーブルを取得する。
これによって取得したROMテーブルのサイズはBIOSの種類によってサイズと情報が若干異なる。ここでは、最低 16 バイトのデータを転送し、0xC0 ブートパラメータを設定している。
このテーブルは、arch/i386/kernel/setup.c で定義されている sys_desc_table_struct 構造体のポインタから参照できる。

ここまで来ると、GAS コードにも大夫慣れて来る。
次は、PS/2 ポインタデバイスにおける処理である。0x1ff のブートパラメータを 0 で初期化した後、INT 11 を呼び出し 32bit のBIOS実装テーブルを取得し、EAX に保存する。
このテーブルを見ることによって、主要なデバイスの有無が確認できる。
ここでは、%al 下位 3 bit目を見る事によって、Pointing Device(PS) が実装されている事を確認できる。これが確認できた場合、0x1ff ブートパラメータに 0xAA を格納する。
尚、このブートパラメータの情報は AUX_DEVICE_INFO マクロによって確認できる。

さて。眼下には APM におけるブートパラメータの設定処理が横たわっている。カーネルオプションによってこれがサポートされていなくとも、動く気もしなくもないが一応中身を追ってみる。
例によってブートパラメータ 0x40 の初期化から処理がはじまる。そして、INT 15 (function 0x53) を呼び出し APM のバージョン及びフラグ情報を取得し、それぞれ AX レジスタ及び CXレジスタに保存する。
エラーチェックを行った後、32 bit プロテクトモードに対応しているかをチェックし、INT 15 (function 0x5304) を呼び出し、APMインターフェイスへの接続を切った後、INT 15 (function 0x5304) を呼び出し、APM インターフェイスへ接続を行っている。その際、出力された結果をブートパラメータ 0x40 に設定している。
尚、このデータも APM_BIOS_INFO マクロが示すアドレスから参照できる。
そして、再度 INT 15 (function 0x5300) を呼び出し、APM のバージョンとフラグ情報をブートパラメータに追加している(何故、再接続を行う前にブートパラメータを設定しないのだろうか)。

ところで、ブートプログラムを書くと言っておきながら、いつも通りソースコードをひたすら読んでばかりいる。しかし、細かい動作がわからず、優秀なドキュメントが存在しない状態では、こうするのがベターなのだろう。
などと言っている間に、ブートパラメータの初期化処理を読み終える。意外に呆気無かった。
結局、linux が設定するブートパラメータは、前回説明した拡張メモリサイズのパラメータと、今回説明した 7 個の計 8 個だけだ。

次はいよいよプロテクトモードへの移行である。

Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/30fc30c830ed30fc30fc-305d306e4/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.