目的
x86-32bitでプロテクトモード中に割り込みが発生した時の動作を概略としてまとめる。
あと、AAで図を書いてみたかった。
前提条件
以下は説明の対象外とする
- ローカル・ディスクリプタ・テーブル(LDT)
- コール・ゲート・ディスクリプタ
- タスク・ゲート・ディスクリプタ
86系のCPUでは、CPUにタスク切り替えをやらせることもできる。
しかし、処理速度や移植性の関係でソフトでタスク切り替えを行うらしい。
タスク実行中に同じ特権レベルの割り込みが発生
動作中のタスクと同じ特権レベルの割り込みが発生した場合。
- 割り込みベクタ番号をインデックスにしてIDTからゲートディスクリプタを参照
(割り込みゲート or トラップゲート) - ゲートディスクリプタに設定されているセグメントセレクタからベースアドレスを取得
- オフセットとベースアドレスから算出される割り込みハンドラの先頭アドレスを実行
割り込みの特権レベルが同じ場合
+-------------+
| IDTR |
+-------------+
| Linear Address
| +---------------+
| IDT | |
+-->+--------------+ | |
| | | |
| | | |
+--------------+ Offset | |
+->|Gate |-------------------------------->(+)-->+---------------+
| |Descriptor |----+ ^ | Interrupt |
| | | | | | Handler |
| +--------------+ | +-------------+ | | |
| | | | | GDTR | | | |
| | | | +-------------+ | | |
| | | | | | +---------------+
| | | | | | | |
| +--------------+ | | GDT | | |
| | +-->+--------------+ | | |
Interrupt | | | | | |
Vector | | | | +---------------+
Number | +--------------+ |
+-------->|Segment |----+
Segment |Descriptor |Base Address
Selector +--------------+
| |
| |
| |
| |
+--------------+
Stack
| |
| |
| |
| |
|---------|
| EIP |
|---------|
| CS |
|---------|
| EFLAGS |
+---------+
| |
| |
タスク実行中に特権レベルが高い割り込みが発生になる。
動作中のタスクより高い特権レベルの割り込みが発生した場合。
- 割り込みベクタ番号をインデックスにIDTのゲートディスクリプタを参照
(割り込みゲート or トラップゲート) - TRが指すTSSを参照し、割り込みの特権レベルに対応するスタックのアドレスを取得
- 割り込み前に実行していたタスクのSS,ESPを割り込みで使用するスタックにプッシュ
- ゲートディスクリプタに設定されているセグメントセレクタからベースアドレスを取得
- オフセットとベースアドレスから算出される割り込みハンドラの先頭アドレスを実行
割り込みの特権レベルが高い場合
+-------------+
| IDTR |
+-------------+
| Linear Address
| +---------------+
| IDT | |
+-->+--------------+ | |
| | | |
| | | |
+--------------+ Offset | |
+->|Gate |-------------------------------->(+)-->+---------------+
| |Descriptor |----+ ^ | Interrupt |
| | |--+ | | | Handler |
| +--------------+ | | | | |
| | | | | +-------------+ | | |
| | | | | | GDTR | | | |
| | | | | +-------------+ | +---------------+
| | | | | | | | |
| +--------------+ | | | | | |
| | | | GDT | | |
Interrupt | | +-->+--------------+ | | |
Vector | | | | | +---------------+
Number | | | | |
| | +--------------+ |
| +-------->|Segment |----+
| Segment |Descriptor |Base Address
| Selector +--------------+
| | |
DPL | | |
| +--------------+
| +-->|TSS |--+
| | |Descriptor | |Base Address
| | +--------------+ |
| | | | |
| | | | |
| | | | | TSS
| | | | +->+--------+
| | | | | |
| | +--------------+ | |
| | | |
| +-------------+ | |
| | TR | | | 特権レベルごとに
| +-------------+ | | Stackアドレスを保持しているらしい
| | |
+------------------------------->| |--+
| | |
+--------+ |
SS:EIP |
+--------------------------------------------+
|
| Interrupt Task
| Stack Stack
| | | | |
| | | | |
| | | | |
| | | | |
| |---------| | |
| | EIP | | |
| |---------| | |
| | CS | | |
| |---------| | |
| | EFLAGS | | |
| |---------| | |
| | ESP |<-+ | |
| |---------| |<----+---------+
| | SS |<-+ | |
+-->+---------+ | |
| | | |
| | | |
メモ
- プロテクトモードで特権レベルを使用するには、最低1つのTSSを用意する必要がある
- TSSには特権レベルごとのスタックのアドレスを保持している
たぶん……
以下が終われば、プロテクトモードで割り込みを許可できる状態になれると思う。
A20ラインの有効化とかあるけど、multiboot specificationに対応しちゃえば考えなくていいよね。
- GDTとGDTRの設定
- IDTとIDTRの設定
- TSSとTRの設定
- 割り込みコントローラの設定
- 割り込みハンドラの実装