Gilles already describeddescribed the general case of an interrupt, the following applies specifically to Linux 2.6 on an Intel architecture (part of this is also based on Intel's specifications).
An interrupt is an event that changes the sequence of instructions executed by the processor.
There are two different kinds of interrupts:
- Synchronous interrupt (Exception) produced by the CPU while processing instructions
- Asynchronous interrupt (Interrupt) issued by other hardware devices
Exceptions are caused by programming errors (f.e. Divide error, Page Fault, Overflow) that must be handled by the kernel. He sends a signal to the program and tries to recover from the error.
The following two exceptions are classified:
- Processor-detected exception generated by the CPU while detecting a anomalous condition; divided into three groups: Faults can generally be corrected, Traps report an execution, Aborts are serious errors.
- Programmed exception requested by the programmer, handled like a trap.
Interrupts can be issued by I/O devices (keyboard, network adapter, ..), interval timers and (on multiprocessor systems) other CPUs. When an interrupt occures, the CPU must stop his current instruction and execute the newly arrived interrupt. He needs to save the old interrupted process state to (probably) resume it after the interrupt is handled.
Handling interrupts is a sensitive task:
- Interrupts can occur at any time, the kernel tries to get it out of the way as soon as possible
- An interrupt can be interrupted by another interrupt
- There are regions in the kernel which must not be interrupted at all
Two different interrupt levels are defined:
- Maskable interrupts issued by I/O devices; can be in two states, masked or unmasked. Only unmasked interrupts are getting processed.
- Nonmaskable interrupts; critical malfunctions (f.e. hardware failure); always processed by the CPU.
Every hardware device has it's own Interrupt Request (IRQ) line. The IRQs are numbered starting from 0. All IRQ lines are connected to a Programmable Interrupt Controller (PIC). The PIC listens on IRQs and assigns them to the CPU. It is also possible to disable a specific IRQ line.
Modern multiprocessing Linux systems generally include the newer Advanced PIC (APIC), which distributes IRQ requests equally between the CPUs.
The mid-step between an interrupt or exception and the handling of it is the Interrupt Descriptor Table (IDT). This table associates each interrupt or exception vector (a number) with a specified handler (f.e. Divide error gets handled by the function divide_error()).
Through the IDT, the kernel knows exactly how to handle the occurred interrupt or exception.
So, what does the kernel when an interrupt occurres?
- The CPU checks after each instruction if there's a IRQ from the (A)PIC
- If so, consults the IDT to map the received vector to a function
- Checks if the interrupt was issued by a authorized source
- Saves the registers of the interrupted process
- Call the according function to handle the interrupt
- Load the recently saved registers of the interrupted process and try to resume it