InterruptDescriptorTable



IDT(Interrupt Descriptor Table:割り込み記述子表)

IDTとは、割り込みと割り込みハンドラ(割り込みに対応する処理)を結びつけるテーブルです。

割り込み(キーボード押下やマウス操作など)が発生した場合に、どのような処理を実行するのかという情報を管理します。

プロテクトモードの場合、ゲート・ディスクリプタと呼ばれるデータ構造体を介してハンドラの処理に移行します。

(リアルモードの場合、割り込みベクターに記述された割り込みハンドラのアドレスを介して、ハンドラの処理を行います。)


IDTのゲート・ディスクリプタとは

ゲート・ディスクリプタとは、割り込みハンドラ関連情報を管理するデータ構造体です。

IDTは、ゲートディスクリプタの配列であり、最大256エントリを設定出来ます。

IDTには、3種類のゲート・ディスクリプタのいずれかがエントリされます。


割り込みゲート・ディスクリプタ

割り込みゲートディスクリプタは、以下のような構造体で表すことができます。

struct gate_descriptor{
    unsigned short  base_low;  /* 割り込み時の実行関数アドレス下位16bit */
    unsigned short  selector;  /* セグメントセレクタ */
    unsigned char   reserved;  /* Intel予約領域 */
    unsigned char   flags;     /* 割り込み種類識別用 */
    unsigned short  base_high; /* 割り込み時の実行関数アドレス上位16bit */
} __attribute__ ((packed));
typedef struct gate_descriptor gate_descriptor_t;

flagsは以下の構造になります。

struct gatedesc_flags{
  unsigned type:4;      /* type */
  unsigned s:1;         /* descriptor type (0 for system segment) */
  unsigned dpl:2;       /* descriptor privilege level */
  unsigned p:1;         /* present bit */
};

IDTR (Interrupt Descriptor Tbale Register)

IDTRとは、IDTの先頭アドレスとサイズ(リミット)を記録するレジスタです。

CPUは割り込み処理を行う際、IDTRを参照して、IDTディスクリプタ・テーブルにアクセスして、割り込みハンドラのアドレスを取得します。

struct idtr{
    unsigned short size;  /* IDTのサイズ */
    unsigned int   base;  /* IDTのアドレス */
} __attribute__ ((packed));
typedef struct idtr idtr_t;

LIDT命令

LIDT命令を使ってIDTRにIDTのサイズとアドレスを格納します。

static inline void
load_idtr(void)
{
    __asm__ __volatile__("lidt %0" :: "m"(idtr));
}

割り込み処理の流れ

割り込みハンドラの呼び出しは以下の流れになります。

  1. 割り込み発生。
  2. IDTRを参照する。
  3. IDTを参照する。
  4. 割り込みハンドラを実行する。
  5. 割り込み発生前の状態に戻る。

関連ページ



スポンサード リンク