Interrupt descriptor table

The Interrupt Descriptor Table (IDT) is a data structure used by the x86 architecture to implement an interrupt vector table. The IDT is used by the processor to determine the correct response to interrupts and exceptions.

The details in the description below apply specifically to the x86 architecture and the AMD64 architecture. Other architectures have similar data structures, but may behave differently.

Use of the IDT is triggered by three types of events: hardware interrupts, software interrupts, and processor exceptions, which together are referred to as "interrupts". The IDT consists of 256 interrupt vectors–the first 32 (0-31 or 00-1F) of which are reserved for processor exceptions.

Real mode

In the 8086 processor, the interrupt table is called IVT (interrupt vector table). The IVT always resides at the same location in memory, ranging from 0x0000 to 0x03ff, and consists of 256 four-byte real mode far pointers (256 × 4 = 1024 bytes of memory).

A real mode pointer is defined as a 16-bit segment and a 16-bit offset into that segment. The segment is expanded internally by the processor to 20 bits by shifting it 4 bits to the left, thus limiting real mode interrupt handlers to the first 1 megabyte of memory. The first 32 vectors are reserved for the processor's internal exceptions, and hardware interrupts may be mapped to any of the vectors by way of a programmable interrupt controller.

On the 80286 and later, the size and locations of the IVT can be changed in the same way as it is done with the IDT in protected mode, i.e. via the LIDT instruction, though it does not change the format of it. The 80286 also introduced the high memory area, which raises the address limit in real mode by 65520 bytes.

A commonly used x86 real mode interrupt is INT 10, the Video BIOS code to handle primitive screen drawing functions such as pixel drawing and changing the screen resolution.

Protected mode

In protected mode, the IDT is an array of 8-byte descriptors stored consecutively in memory and indexed by an interrupt vector. These descriptors may be either interrupt gates, trap gates or task gates. Interrupt and trap gates point to a memory location containing code to execute by specifying both a segment (present in either the GDT or LDT) and an offset within that segment. The only difference between these two is that an interrupt gate will disable further processor handling of hardware interrupts, making it especially suitable to service hardware interrupts, while a trap gate will leave hardware interrupts enabled and is thus mainly used for handling software interrupts and exceptions. Finally, a task gate will cause the currently active task-state segment to be switched, using the hardware task switch mechanism to effectively hand over use of the processor to another program, thread or process.

The protected mode IDT may reside anywhere in physical memory. The processor has a special register (IDTR) to store both the physical base address and the length in bytes of the IDT. When an interrupt occurs, the processor multiplies the interrupt vector by 8 and adds the result to the IDT base address. With help of the IDT length, the resulting memory address is then verified to be within the table; if it is too large, an exception is generated. If everything is okay, the 8-byte descriptor stored at the calculated memory location is loaded and actions are taken according to the descriptor's type and contents.

A fully populated IDT is 2 KB (256 entries of 8 bytes each) in length. It is not necessary to use all of the possible entries: it is sufficient to populate the IDT up to the highest interrupt vector used, and set the IDT length portion of the IDTR accordingly. Vectors 0-31 are reserved by Intel for processor generated exceptions (general protection fault, page fault, etc.). Though currently only vectors 0-18 are used by the processor, future processors may create incompatibilities for broken software which use these vectors for other purposes.

Hardware-generated exceptions

All INT_NUM between 0x0 and 0x1F, inclusive, are reserved for exceptions; INT_NUM bigger than 0x1F are used for interrupt routines. (Note that the IBM PC did not always obey this rule, for instance using interrupt 5 to indicate the Print Screen key was pressed.)

INT_NUM Short Description PM
0x00 Division by zero
0x01 Single-Byte Interrupt (usually used for debugger breakpoint)
0x02 NMI
0x03 Breakpoint
0x04 Overflow
0x05 Bounds
0x06 Invalid Opcode
0x07 Coprocessor not available
0x08 Double fault
0x09 Coprocessor Segment Overrun (386 or earlier only)
0x0A Invalid Task State Segment
0x0B Segment not present
0x0C Stack Fault
0x0D General protection fault
0x0E Page fault
0x0F reserved
0x10 Math Fault
0x11 Alignment Check
0x12 Machine Check
0x13 SIMD Floating-Point Exception
0x14 Virtualization Exception
0x15 Control Protection Exception

Hooking

Some Windows programs hook calls to the IDT. This involves writing a kernel mode driver that intercepts calls to the IDT and adds in its own processing. This has never been officially supported by Microsoft, but was not programatically prevented on its operating systems until 64-bit versions of Windows, where a driver that attempts to use a kernel mode hook will cause the machine to bug check.[1]

References

  1. "Patching Policy for x64-Based Systems". 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.
General
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.