1.1. Interrupt Descriptor Table(IDT)

프로세서에게 인터럽트 혹은 exception 이 걸렸을 경우에 수행해야 할 핸들러의 주소를 저장해 놓은 것을 인터럽트 혹은 exception vector 라고 한다.

인텔의 프로세서에서는 이러한 인터럽트 혹은 exception 핸들러들의 벡터와 벡터의 정보 등을 저장해 두는 구조체를 IDT(Interrupt Descriptor Table) 라고 부른다. 이들 IDT 구조체들은 인텔 아키텍쳐의 특이한 자료 구조인 '게이트' [1] 의 형태를 이루고 있는데, 실제 IDT 에 들어갈 수 있는 게이트들은 Task gate, Trap gate, Interrupt Gate 의 세가지가 있다. 리눅스의 경우는 IDT 에 interrupt gate 와 trap gate 만을 사용한다.

1.1.1. IDTR

펜티엄에는 IDTR 이라 불리우는 특별한 레지스터가 존재한다. 이 레지스터는 시스템의 IDT 가 존재하는 메모리 주소의 베이스 어드레스와 IDT entry 의 갯수가 저장되기로 약속된 레지스터이다. 이 레지스터는 크기가 48 비트로써, 상위 32 비트에는 IDT 가 시작되는 곳의 베이스 어드레스가 저장되며 하위 16비트에는 IDT 엔트리의 갯수가 담겨져 있다.

일단 인터럽트나 예외상황(execption 을 '예외상황' 이란 말로 통일하도록 하겠다.)이 발생하면, 프로세서는 IDTR 을 참조하여 그 베이스 어드레스로부터 인터럽트 혹은 예외상황의 번호에 해당하는 게이트를 호출한다. [2] 즉, 다음 그림과 같이 IDT 에서 호출해야 할 게이트 디스크립터를 찾는 것이다 :

그림 1-1. Relationship of the IDTR and IDT

위 그림처럼 인터럽트 벡터를 가지고 해당하는 IDT 엔트리를 찾은 후에는 다음 그림처럼 해당 엔트리에 있는 게이트를 호출한다 :

그림 1-2. Interrupt Procedure call

1.1.2. Interrupt Descriptor Table Structure

각각의 IDT 의 엔트리들은 대개 다음과 같은 구조로 이루어져 있다 :

그림 1-3. IDT Gate Descriptors

위 그림에서 특히 주목해야 할 부분은 없다. 일반적인 게이트 디스크립터(gate descriptor) 들은 모두 윗 그림과 비슷한 구조를 가진다.

주석

[1]

게이트란 인텔 프로세서들에서 정의해서 사용하는 특이한 구조인데, 게이트는 시스템에 서로 다른 privilege 레벨의 핸들러 혹은 procedure 를 호출하기 위해서 정의하고 있는 일종의 'gateway' 와 같은 역할을 하는 구조체이다. 이 구조체에는 호출할 핸들러 혹은 procedure 의 주소에 대한 정보, privilege level 에 대한 정보와 같은 것들이 담겨져 있다. 주로 이러한 게이트들은 64비트의 크기를 가진다. 인텔에서 정의하는 게이트는 call gate, task gate, interrupt gate, trap gate 등이 존재하며, IDT 에 들어갈 수 있는 게이트는 여기서 call gate 를 제외한 세가지 gate 들이다.

[2]

원문에서는 CALL to a gate 라고 표기하고 있습니다. 풍기는 느낌으로 이해하세요 :-)