《Understanding the Linux kernel》学习笔记 Chapter 4: Interrupts and ExceptionsM

来源:互联网 发布:java反射调用方法 编辑:程序博客网 时间:2024/04/30 09:29

An interrupt is usually defined as an event that alters the sequence of instructions executed by a processor.

Interrupts are often divided into synchronous and asynchronous interrupts:

  • Synchronous interrupts are produced by the CPU control unit while executing instructions and are called synchronous because the control unit issues them only after terminating the execution of an instruction.
  • Asynchronous interrupts are generated by other hardware devices at arbitrary times with respect to the CPU clock signals.
Intel microprocessor manuals designate synchronous and asynchronous interrupts as exceptions and interrupts, respectively.

4.1 The Role of Interrupt Signals

As the name suggests, interrupt signals provide a way to divert the processor to code outside the normal flow of control.

There is a key difference between interrupt handling and process switching: the code executed by an interrupt or by an exception handler is not a process. Rather, it is a kernel control path that runs at the expense of the same process that was running when the interrupt occurred.


4.2 Interrupts and Exceptions

The Intel documentation classifies interrupts and exceptions as follows:

  • Interrupts: Maskable interrupts, Nonmaskable interrupts
  • Exceptions: Processor-detected exceptions (Faults, Traps, Aborts), Programmed exceptions
Each interrupt or exception is identified by a number ranging from 0 to 255; Intel calls this 8-bit unsigned number a vector. The vectors of nonmaskable interrupts and exceptions are fixed, while those of maskable interrupts can be altered by programming the Interrupt Controller.

4.2.1 IRQs and Interrupts

Each hardware device controller capable of issuing interrupt requests usually has a single output line designated as the Interrupt ReQuest (IRQ) line. All existing IRQ lines are connected to the input pins of a hardware circuit called the Programmable Interrupt Controller, which performs the following actions:

  1. Monitors the IRQ lines, checking for raised signals. If two or more IRQ lines are raised, selects the one having the lower pin number.
  2. If a raised signal occurs on an IRQ line: a. Converts the raised signal received into a corresponding vector. b. Stores the vector in an Interrupt Controller I/O port,  thus allowing the CPU to read it via the data bus. c. Sends a raised signal to the processor INTR pin -- that is, issues an interrupt. d. Waits until the CPU acknowledges the interrupt signal by writing into one of the Programmable Interrupt Controllers (PIC) I/O ports; when this occurs, chears the INTR line.
  3. Goes back to step 1.

4.2.2 Exceptions

4.2.3 Interrupt Descriptor Table

A system table called Interrupt Descriptor Table (IDT) associates each interrupt or exception vector with the address of the corresponding interrupt or exception handler. The IDT must be properly initialized before the kernel enables interrupts.

The IDT may include three types of descriptors. The descriptors are:

  • Task gate  Includes the TSS selector of the process that must replace the current one when an interrupt signal occurs.
  • Interrupt gate  Includes the Segment Selector and the offset inside the segment of an interrupt or exception handler. While transferring control to the proper segment, the processor clears the IF flag, thus disabling further maskable interrupts.
  • Trap gate  Similar to an interrupt gate, except than while transferring control to the proper segment, the processor does not modify the IF flag.

4.2.4 Hardware Handling of Interrupts and Exceptions

  1. Determines the vector i (0 <= i <= 255) associated with interrupt or the exception.
  2. Read the ith entry of the IDT referred by the idtr register.
  3. Gets the base address of the GDT from the gdtr register and looks in the GDT to read the Segment Descriptor identified by the selector in the IDT entry.
  4. Makes sure the interrupt was issued by an authorized source.
  5. Checks whether a change of privilege levelis taking place.
  6. If a fault has occurred, it loads cs and eip with the logical address of the instruction that caused the exception so that it can be executed again.
  7. Saves the contents of eflags, cs, and eip in the stack.
  8. If the exception carries a hardware error code, it saves it on the stack.
  9. Loads cs and eip, respectively, with the Segment Selector and the Offset fields of the Gate Descriptor stored in the ith entry of the IDT.
After the interrupt or exception is processed, the corresponding handler must relinquish control to the interrupted process by issuing the iret instruction, which forces the control unit to:
  1. Load the cs, eip, and eflags registers with the values saved on the stack.
  2. Check whether the CPL of the handler is equal to the value contained in the two last significant bits of cs. If so, iret concludes execution; otherwise, go to the next step.
  3. Load the ss and esp registers from the stack and return to the stack associated with the old privilege level.
  4. Examine the contents of the ds, es, es, fs, and gs segment registers.

4.3 Nested Execution of Exception and Interrupt Handlers

4.4 Initializing the Interrupt Descriptor Table

4.5 Exception Handling

4.6 Interrupt Handling

4.7 Softirqs and Tasklets

4.8 Work Queues

4.9 Returning from Interrupts and Exceptions

0 0
原创粉丝点击