技術日誌

DB,Java,セキュリティ,機械学習など。興味のあることを雑多に学ぶ

30日OS自作本6日目

6日目は割り込みハンドラの実装&呼び出しを行った。

キーボード入力に反応.マウスはまだ動かない.

GDTの仕組み

GDTRという48ビットのレジスタにGDTを配置した番地(開始地点)とリミット(開始地点からどこまでGDTか)を書き込む

  • GDTRの最初の2バイトはリミットを表す
  • 残りの4バイトでGDTが置いてある番地を表す
  • 0xFFFF000027000x270000~0x27ffffまでGDTとして扱うという意味なる。
    • GDT自体のサイズは8バイトであるからこの場合GDTは8192個設定可能となる。

構造体の解説

struct SEGMENT_DESCRIPTOR {
    short limit_low, base_low;
    char base_mid, access_right;
    char limit_high, base_high;
};

上記の構造体の説明。文章だけだとこんがらがったので画像に起こして理解した。画像とコードの対応がちょっとおかしいが、C言語は4bit長の変数がないらしく、limit_highの上位4bitにセグメント属性を書き込むようになっている。最終的にGDTに書き込む長さとしてはlimit_highは実質4bit,access_rightは実質12bitとなっている。

構造体上での表現


63       55       47       39       31       23       15       7        0
+--------+--------+--------+--------+--------+--------+--------+--------+
|base_hi |limit_hi|   ar   |base_mid|     base_low    |    limit_low    |
+--------+--------+--------+--------+--------+--------+--------+--------+



CPUの仕様上のデスクリプタ
※limit_highの上位4bitはアクセス属性の続きになります。だから実際はCPUは上の構造体を以下の形式で扱います。

63       55       47       39       31       23       15       7        0
+--------+----+----+--------+--------+--------+--------+--------+--------+
|base_hi |ar  |l_hi|   ar   |base_mid|     base_low    |    limit_low    |
+--------+----+----+--------+--------+--------+--------+--------+--------+


※入りきらない変数名は省略しています

アクセス権の設定値

arの中身です。

設定値 hex 意味
00000000 0x00 GDTが未使用であることを示す
10010010 0x92 システム専用readのみ。実行不可
10011010 0x9a システム専用read可能&実行可能
11110010 0xf2 アプリケーション用readのみ。実行不可
11111010 0xfa アプリケーション用read可能&実行可能

セキュリティ

CPUにはアプリケーションモードとシステムモードがある。

  • アプリケーションモードの時にLGDTの実行を制限(監視)する
  • アプリケーションモードの時にシステム専用のセグメントの読み書きを制限(監視)する

実行中のプログラムが0x9a,0xfaどちらのセグメントに配置されているかでモードの判別を行う。 アプリケーションモード時にLGDTの実行を制限しているのはGDTの再設定ができてしまうから。*1

割り込み

割り込みにはGDTとIDTの初期化に加えて、PICの初期化が必要

PICとは?

programmable intrrupt controllerの略

CPUは単独では一つしか割り込みを扱えない。 複数(8個)の割り込みを一つの割り込み信号にまとめる装置がPIC

割り込み信号をIRQといい0~8の数字が振られPICの各ピンに対応している

本中のPICは2連結(マスター:スレーブ)になっているらしく、15個のIRQが扱える*2

  • マウス:IRQ12
  • キーボード:IRQ1

はここに記載があるものと一緒。何かの標準規格?

http://d.hatena.ne.jp/wocota/20090302/1235985661

ハードウェア的にはIntel8259と呼ばれるものと同一?

PICの接続をマスターの2番ピンにさしてるのはIBMのおじさんが決めた、的な下りがあるけど、 IBMのおじさんが決めた規格があってInterl人もそれに添って決めているということなのかな。

PICのレジスタ

全て8bit

  • IMR:innterrupt mask register
    • 1が立っている位置に対応しているIRQの割り込みを無視する。
  • ICW:1~4の合計4バイトがあるが何に使っているかよくわからない。プログラムの設定値以外は設定できないらしい。
    • ICW3:スレーブが刺さってるマスタのピンを登録。つまり0b00000100で固定。
      • 下位ビットからpin 0,pin 1,pin 2,...という対応だと思う。
      • 他の値は設定できない。
    • ICW2:IRQ0~15をINTのどれで受け取るかを指定。以下に設定例を示す
io_out8(PIC0_ICW2, 0x20  ); /* IRQ0-7は、INT20-27で受ける */
io_out8(PIC1_ICW2, 0x28  ); /* IRQ8-15は、INT28-2fで受ける */

割り込みの設定

キーボード(IRQ1)の例

  • IDTに0x21bの割り込みの祭に呼び出す関数_asm_inthandler21(アセンブリ)を設定
    • Cから呼び出せないIRETD命令が必要なためアセンブリで書く必要がある。
    • 短い。レジスタの退避、Cの関数呼び出し、IRETD命令程度しかやっていない。
  • _asm_inthandler21からC言語の関数inthandler21を呼び出す
    • キーボードが押された際に画面に出力

感想

  • 正直前章まではプログラムで絵を書いてる要素が強かったが今回から結構OSっぽくなってきたと思う。
  • ググりながら読みましたが英語と配線地獄のデータシートとにらめっこの日々を思い出した。*3

*1:いい例えが思いつかないが刑務所のセキュリティがどんだけ厳しくても、受刑者が自分の刑期を自由に設定されちゃ意味ないよね。的な感じ。

*2:1個はPICを連結しているピンで塞がるため16-1で15個

*3:まぁ楽しかったのですが。