인터럽트 서술자 테이블
인터럽트 서술자 테이블(Interrupt descriptor table, IDT)은 인터럽트 벡터 테이블을 구현하기 위해 X86 아키텍처에서 사용되는 데이터 구조체이다. IDT는 프로세서가 인터럽트와 예외에 대한 정확한 반응을 결정하기 위해 사용된다.
아래에서 설명할 자세한 부분들은 x86 아티텍처와 AMD64 아키텍처에서 적용되는 것이다. 다른 아키텍처들은 비슷한 구조체를 갖지만 행동은 조금 다를 수 있다.
IDT의 사용은 다음 3 종류의 이벤트들에 의해서 발생된다. 인터럽트로 불리는 하드웨어 인터럽트, 소프트웨어 인터럽트 그리고 프로세서 예외이다. IDT는 256개의 인터럽트 벡터들로 이루어져 있으며 처음 32개는 프로세서 예외를 위해 예약되어 있다.
리얼 모드
[편집]인텔 8086 프로세서에서, IDT는 0x0000
부터 0x03ff
,까지의 메모리 주소에서 위치하며, 256개의 4바이트 리얼 모드 포인터들로 이루어져 있다. 인텔 80286과 그 다음부터는 IDT의 구조는 그대로지만 크기와 위치가 보호 모드 같은 방식으로 바뀌었다. 리얼 모드 포인터는 세그먼트에 대한 16비트 세그먼트 주소와, 16비트 오프셋으로 정의되어 있다. 세그먼트 주소는 (리얼 모드 인터럽트 핸들러를 주소 지정 가능한 메모리의 1 메가바이트로 제한함으로써) 내부적으로 프로세서에 의해서 20비트로 확장되었다. 처음 32 벡터들은 프로세서의 내부 예외를 위해 예약되었으며, 하드웨어 인터럽트들은 다른 어느 벡터에도 매핑될 수 있다.
x86 리얼 모드에서 주로 사용되는 인터럽트는 INT 10
이다.
보호 모드
[편집]보호 모드에서, IDT는 메모리에 연속적으로 저장된, 그리고 인터럽트 벡터에 의해 색인화된 8바이트 디스크립터의 배열이다. 이 디스크립터들은 인터럽트 게이트나 트랩 게이트 또는 태스크 케이트일 수 있다. 인터럽트와 트랩 게이트는 세그먼트와 세그먼트 내의 오프셋에 명시된, 실행되는 코드를 포함하는 메모리 위치를 가리킨다. 이 둘 사이의 단 하나의 차이점은 인터럽트 게이트는 (하드웨어 인터럽트를 다루는) 프로세서를 서비스 하드웨어 인터럽트에 맞추어서 그 이상의 것이 금지될 것이고, 트랩 게이트는 하드웨어 인터럽트를 사용 가능케 하고 소프트웨어 인터럽트와 예외를 다루는데 쓰이게 된다. 마지막으로, 태스크 게이트는 하드웨어 태스크 스위치 메커니즘을 사용해 효과적으로 프로세서의 사용을 다른 프로세스나 스레드에 넘겨주는 것을 목적으로 현재 활성화된 태스크 상태 세그먼트를 바뀌게 한다.
보호 모드 IDT는 물리 메모리의 어느 곳이는 위치할 수 있다. 프로세서는 물리 베이스 주소와 IDT의 바이트 길이를 저장하기 위해 특별한 레지스터 (IDTR
)를 가진다. 인터럽트가 발생하면, 프로세서는 인터럽트 벡터에 8을 곱해서 IDT 베이스 어드레스에 그 결과 값을 더한다. IDT 길이의 도움으로 메모리 주소 결과는 테이블 내에서 확인된다. 만약 너무 크다면 예외가 생성되고, 완벽하다면 계산된 메모리 위치에 저장된 8바이트 디스크립터는 로드되고 디스크립터의 종류와 내용에 따라 행동을 하게 된다.
완전한 IDT는 2KB의 길이를 갖는다. 가능한 엔트리들을 모두 사용하는 것은 필요치 않다. IDT의 수를 사용되는 인터럽트 벡터의 가장 높은 수준으로 올리고 IDT 길이를 적절하게 IDTR
의 비율로 맞추면 충분하다. 0-31 벡터들은 인텔에 의해서 프로세서에서 생성된 예외들을 위해 예약되었다. 비록 현재 단지 0-18 벡터들만 프로세서에 의해서 사용되지만, 미래에는 프로세서가 이 벡터들이 다른 목적으로 사용되는 고장난 소프트웨어를 위해 불화합성을 만들 것이다.
하드웨어에서 생성된 예외들
[편집]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 부동소수점 예외 |
후킹
[편집]몇몇 윈도우 프로그램들은 IDT를 호출하기 위해 후킹한다. 이것은 커널 모드 장치 드라이버를 쓰는 것을 포함한다(IDT 호출을 가로채고 자신의 과정을 넣는다). 이것은 마이크로소프트에서 정식으로 지원하지 않지만, 64비트 버전 까지는 프로그램적으로 막혀있지는 않다(커널 모드 후킹을 사용하려는 시도를 하는 드라이버는 시스템의 버그 체크를 유발할 것이다).[1]
각주
[편집]- ↑ “Patching Policy for x64-Based Systems”. 2010년 12월 16일에 원본 문서에서 보존된 문서. 2015년 10월 13일에 확인함.
If the operating system detects one of these modifications or any other unauthorized patch, it will generate a bug check and shut down the system.
외부 링크
[편집]- Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A:System Programming Guide, Part 1 (see CHAPTER 6, INTERRUPT AND EXCEPTION HANDLING and CHAPTER 10, ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER)]
- Interrupt Descriptor Table at OSDev.org