Interrupt descriptor table

Ahn9807 (토론 | 기여)님의 2023년 2월 11일 (토) 03:04 판 (새 문서: 분류: 예외적 제어흐름 == 개요 == '''인터럽트 디스크립터 테이블 (Interrupt Descriptor Table''' ('''IDT'''))은 인터럽트 벡터 테이블을 구현하기 위해 X86 아키텍처에서 사용되는 데이터 구조체이다. IDT는 프로세서가 인터럽트와 예외에 대한 정확한 반응을 결정하기 위해 사용된다. 아래에서 설명할 자세한 부분들은 x86 아티텍처와 AMD64 ...)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)


개요

인터럽트 디스크립터 테이블 (Interrupt Descriptor Table (IDT))은 인터럽트 벡터 테이블을 구현하기 위해 X86 아키텍처에서 사용되는 데이터 구조체이다. IDT는 프로세서가 인터럽트와 예외에 대한 정확한 반응을 결정하기 위해 사용된다.

아래에서 설명할 자세한 부분들은 x86 아티텍처와 AMD64 아키텍처에서 적용되는 것이다. 다른 아키텍처들은 비슷한 구조체를 갖지만 행동은 조금 다를 수 있다.

IDT의 사용은 다음 3 종류의 이벤트들에 의해서 발생된다. 인터럽트로 불리는 하드웨어 인터럽트, 소프트웨어 인터럽트 그리고 프로세서 예외이다. IDT는 256개의 인터럽트 벡터들로 이루어져 있으며 처음 32개는 프로세서 예외를 위해 예약되어 있다.

IDT는 CPU의 IDTR레지스터에 저장된다. 이러한 IDT는 LIDT, SIDT 명령어를 통해서 loaded되고 stored될 수 있다.

IDTR
Name Bit Description
Limit 0..15 Defines the length of the IDT in bytes - 1 (minimum value is 100h, a value of 1000h means 200h interrupts).
Base 16..47 This 32 bits are the linear address where the IDT starts (INT 0)

리얼 모드

인텔 8086 프로세서에서, IDT는 0x0000 부터 0x03ff,까지의 메모리 주소에서 위치하며, 256개의 4바이트 리얼 모드 포인터들로 이루어져 있다. 인텔 80286과 그 다음부터는 IDT의 구조는 그대로지만 크기와 위치가 보호 모드 같은 방식으로 바뀌었다. 리얼 모드 포인터는 세그먼트에 대한 16비트 세그먼트 주소와, 16비트 오프셋으로 정의되어 있다. 세그먼트 주소는 (리얼 모드 인터럽트 핸들러를 주소 지정 가능한 메모리의 1 메가바이트로 제한함으로써) 내부적으로 프로세서에 의해서 20비트로 확장되었다. 처음 32 벡터들은 프로세서의 내부 예외를 위해 예약되었으며, 하드웨어 인터럽트들은 다른 어느 벡터에도 매핑될 수 있다.

리얼 모드에서 IDT는 원래 Interrupt Vector로 불려졌다. 즉 IDT는 protected mode에서 IDT의 counter part이다. 

보호 모드

보호 모드에서, IDT는 메모리에 연속적으로 저장된, 그리고 인터럽트 벡터에 의해 색인화된 8바이트 디스크립터의 배열이다. 이 디스크립터들은 인터럽트 게이트나 트랩 게이트 또는 태스크 케이트일 수 있다. 인터럽트와 트랩 게이트는 세그먼트와 세그먼트 내의 오프셋에 명시된, 실행되는 코드를 포함하는 메모리 위치를 가리킨다. 이 둘 사이의 단 하나의 차이점은 인터럽트 게이트는 (하드웨어 인터럽트를 다루는) 프로세서를 서비스 하드웨어 인터럽트에 맞추어서 그 이상의 것이 금지될 것이고, 트랩 게이트는 하드웨어 인터럽트를 사용 가능케하고 소프트웨어 인터럽트와 예외를 다루는데 쓰이게 된다. 마지막으로, 태스크 게이트는 하드웨어 태스크 스위치 메커니즘을 사용해 효과적으로 프로세서의 사용을 다른 프로세스나 스레드에 넘겨주는 것을 목적으로 현재 활성화된 태스크 상태 세그먼트를 바뀌게 한다.

보호 모드 IDT는 물리 메모리의 어느 곳이는 위치할 수 있다. 프로세서는 물리 베이스 주소와 IDT의 바이트 길이를 저장하기위해 특별한 레지스터 (틀:Code)를 가진다. 인터럽트가 발생하면, 프로세서는 인터럽트 벡터에 8을 곱해서 IDT 베이스 어드레스에 그 결과 값을 더한다. IDT 길이의 도움으로 메모리 주소 결과는 테이블 내에서 확인된다. 만약 너무 크다면 예외가 생성되고, 완벽하다면 계산된 메모리 위치에 저장된 8바이트 디스크립터는 로드되고 디스크립터의 종류와 내용에 따라 행동을 하게 된다.

완전한 IDT는 2KB의 길이를 갖는다. 가능한 엔트리들을 모두 사용하는 것은 필요치 않다. IDT의 수를 사용되는 인터럽트 벡터의 가장 높은 수준으로 올리고 IDT 길이를 적절하게 IDTR의 비율로 맞추면 충분하다. 0-31 벡터들은 인텔에 의해서 프로세서에서 생성된 예외들을 위해 예약되었다. 비록 현재 단지 0-18 벡터들만 프로세서에 의해서 사용되지만, 미래에는 프로세서가 이 벡터들이 다른 목적으로 사용되는 고장난 소프트웨어를 위해 불화합성을 만들 것이다.

64bit Long mode

AMD64 Long mode에서 IDT의 구조는 살짝 바뀐다. IDTR레지스터의 base field가 64비트로 바뀌며, IDT의 entry가 64비트로 바꾸게 된다.

하드웨어에서 생성된 예외들

0x0과 0x1F 사이의 모든 포괄적인 INT_NUM은 예외들을 위해 예약되어 있다. 0x1F보다 큰 INT_NUM는 인터럽트 루틴을 위해 사용된다.

INT_NUM 간단한 설명
0x00 0으로 나누기
0x01 디버거
0x02 NMI
0x03 브레이크포인트
0x04 오버플로우
0x05 Bounds
0x06 유효하지 않은 옵코드
0x07 보조 프로세서 사용 불능
0x08 Double fault
0x09 보조 프로세서 세그먼트 오버런 (386 또는 그 이전 버전만 해당)
0x0A 유효하지 않은 태스크 상태 세그먼트
0x0B 존재하지 않은 세그먼트
0x0C 스택 부재
0x0D General protection fault
0x0E 페이지 부재
0x0F 예약되어 있음
0x10 Math Fault
0x11 정렬 체크
0x12 머신 체크
0x13 SIMD 부동소수점 예외