Kernel note (1) -- Understanding interrupt (1)

Source: Internet
Author: User
We always think that understanding interrupt is the beginning of understanding the kernel. Interruptions have far exceeded the scope of peripheral services, and are an important part of the modern architecture.
1. Basic Input and Output Modes
There are three basic Input and Output Modes of modern architecture:
(1) program query:
The CPU periodically asks if the external device is ready. The obvious disadvantage of this method is the waste of CPU resources and low efficiency.
However, do not consider this method as a bad one (pretty women are not necessarily good, pretty women are usually cute ), generally, low efficiency is caused by the fact that the CPU has nothing to do for most of the time. This round robin method has its own place to apply it. For example, in a network drive, an Interface is usually interrupted every time it receives a packet. For high-speed networks, thousands of packets can be received every second. Under such loads, the system performance will be greatly impaired.
To improve system performance, kernel developers have developed an optional query-based NAPI (new API) for network subsystems ). When the system has a high-traffic high-speed interface, the system usually collects enough packets instead of immediately interrupting the CPU.
(2) interrupt mode
This is the most common way for modern CPUs to communicate with peripheral devices. Compared with Round Robin, this method does not waste scarce CPU resources, so it is efficient and flexible. The disadvantage of the interrupt handling method is that each character is transmitted with an interrupt, the interrupt controller is started, and the site must be retained and restored to continue the execution of the original program, which takes a lot of work, in this way, if a large amount of data exchange is required, the system performance will be very low.
(3) DMA mode
It is usually used for high-speed devices. The device requests direct access to the memory without CPU interference. However, this method requires a DMA controller, which increases hardware costs. Before DMA data transmission, the DMA Controller applies to the CPU for bus control. If the CPU permits, the control is handed over. Therefore, during data exchange, the bus control is controlled by the DMA controller, after the transfer ends, the DMA controller returns the control of the bus to the CPU.

2. Interruption Overview
2.1. interrupt vector
X86 supports 256 interrupt vectors, numbered 0 ~ 255. They are divided into two types:
(1) exceptions, caused by the CPU, are also called synchronization interruptions and cannot be blocked by the CPU; they are also divided into Faults (exception correction can be performed again after recovery ), traps (the last command that executes the trap command after the response is returned) and Aborts (the system can only be stopped because the system cannot be recovered );
(2) interruption caused by external devices. It is divided into two types: Shielded interrupt (INTR) and non-shielded interrupt (NMI ).
Linux allocates 256 interrupt vectors as follows:
(1) 0 ~ 31 is abnormal and unshielded, and is actually retained by Intel.
(2) 32 ~ 47. Blocked interruptions.
(3) remaining 48 ~ 255 is used to identify soft interruptions. Linux only uses one of them, namely 128 (0x80), to implement system calls. When a user program executes an int 0x80, it will fall into the kernel state and execute the kernel function system_call (). This function is related to the specific architecture.
2.2 blocked interruptions
X86 uses two 8259A interrupt controller chips to manage 15 external interrupt sources ,:


An external device must use a moderate disconnection. First, it must request an IRQ. The interrupt vector corresponding to the IRQn of the disconnection is n + 32, the ing between IRQ and vector can be modified through the interrupt controller port. The initialization of 8259A in X86 and the iring between IRQ and vector are completed in the init_8259A () function (in arch/i386/kernel/i8259.c.
The CPU uses the INTR pin to receive interrupt requests from the 8259A, And the CPU can block external interruptions by clearing the EFLAG interrupt flag (IF. When IF = 0, prohibit any external I/O requests, that is, the disconnection (corresponding command cli ). In addition, the interrupt controller has an eight-bit interrupt shielding register (IMR), each of which corresponds to one of the 8259A. If you want to disable a disconnection, the corresponding position is 1. To enable it, set 0.
The IF flag can be set or cleared using the commands STI and CLI. These two commands can be executed only when CPL of the program is <= IOPL. Otherwise, a general protective exception will occur (in, ins, out, outs, cli, sti can be executed only when CPL <= IOPL, these commands are called I/O sensitive commands ).
The IF flag is also affected by the following operations:
(1) The PUSHF command saves the EFLAGS content to the stack and can be modified there. POPF can write modified content to the EFLAGS register.
(2) The task switching and IRET commands load the EFLAGS register. Therefore, you can modify the IF flag.
(3) When an interrupt is handled through the interrupt door, the IF flag is automatically cleared, so as to prevent interruption. However, the trap door will not reset IF.
2.3 exceptions and unshielded interruptions
An exception is an internal interruption of the CPU, that is, an exception occurs when the CPU executes a specific command. Unshielded interruptions are exceptions caused by hardware errors in the computer. It can be seen that the two have nothing to do with external I/O interfaces. Intel treats unshielded interruptions as an exception. Therefore, the exceptions mentioned later include unshielded interruptions. When the CPU executes an exception processing program, it no longer serves other exceptions or can block the interrupted request service. That is to say, when an exception is returned, the CPU clears the IF bit of EFLAG, prohibit any blocked interruptions (IF not, prohibit exceptions and non-blocked interruptions ). However, if another exception occurs, the CPU locks (the CPU has the buffer exception capability). After the exception is processed, the system responds to the exception. The exception interrupt vectors we discuss here are 0 ~ 31, excluding system calls (the interrupt vector is 0x80 ).

2.4. Interrupt Descriptor Table
2.4.1. Interrupt Descriptor
In real address mode, the CPU uses 1 K Bytes starting from 0 as an interrupt vector table. Each table entry occupies four bytes, which are composed of two bytes of segment address and two bytes of offset. The resulting address is the entry address of the corresponding interrupt handler. However, in the protection mode, the interrupt vector table composed of four-byte table items obviously does not meet the requirements. This is because, except for the two-byte segment descriptors, the offset must be expressed in four bytes; there must be information that reflects the mode switching. Therefore, in protection mode, the Table items in the Interrupt vector Table are composed of 8 bytes. The Interrupt vector Table is also called the Interrupt Descriptor Table IDT (Interrupt Descriptor Table ). Each table item in the table is called a gate descriptor. The "gate" means that when an interrupt occurs, you must first use these doors before entering the corresponding processing program. The general format of the gate descriptor is as follows:

The Interrupt Descriptor Table can contain three types of gate descriptors:
(1) Interrupt gate)
The type code is 110, which contains the segment separator and intra-segment offset of an interrupt or exception handling program. When the control enters the interrupt processing program through the interrupt door, the processor clears the IF sign, that is, the disconnection, to avoid nested interruptions. The DPL (Descriptor Privilege Level) in the interrupt gate is 0. Therefore, user-mode processes cannot access Intel's interrupt gate. All interrupt handlers are activated by the interrupt gate and all are limited to the kernel state. The code for setting the interrupt gate is as follows: // N is the interrupt vector number, and addr is the address of the interrupt handler, which is located in arch/i386/kernel/traps. c
Void set_intr_gate (unsigned int n, void * addr)
{// Type = 14, dpl = 0, selector = __kernel_cs
_ Set_gate (idt_table + n, 14,0, addr ,__ KERNEL_CS );
}

Idt_table is the Interrupt Descriptor Table, which is defined in arch/i386/kernel/traps. c, as follows: // Interrupt Descriptor Table
Struct desc_struct idt_table [256] _ attribute _ (_ section _ (". data. idt") ={{ 0, 0 },};
// Descriptor Structure
Struct desc_struct {
Unsigned long a, B;
};

(2) Trap gate)
The type code is 111, which is similar to the interrupt gate. The only difference is that the IF flag remains unchanged when the control enters the processing program through the trap gate, that is, the interruption is not disabled. The configuration code is as follows: Static void _ init set_trap_gate (unsigned int n, void * addr)
{
_ Set_gate (idt_table + n, 15, 0, addr ,__ KERNEL_CS );
}

(3) Task gate)
The format of the task gate descriptor in IDT is the same as that in GDT and LDT. It contains a selection operator for the TSS segment of the task. This task is used to handle exceptions or interruptions. in Linux, it is used to process Double fault. The configuration code is as follows: Static void _ init set_task_gate (unsigned int n, unsigned int gdt_entry)
{
_ Set_gate (idt_table + n, 5, 0, 0, (gdt_entry <3 ));
}

Their respective formats are as follows:

In addition, there is a System gate in Linux, which is used to handle abnormal overflow in the user State, bound and int 0x80 calls by the System; and system interrupt gate, used to process int3, so that the Assembly command int3 can be called in user mode. Static void _ init set_system_gate (unsigned int n, void * addr)
{
_ Set_gate (idt_table + n, 15,3, addr ,__ KERNEL_CS );
}
// Set the system call gate descriptor, which is called by trap_init () in trap. c.
Set_system_gate (SYSCALL_VECTOR, & system_call );

// Set the system interrupt Gate
Static inline void set_system_intr_gate (unsigned int n, void * addr)
{
_ Set_gate (idt_table + n, 14, 3, addr, _ KERNEL_CS );
}

// In arch/i386/kernel/traps. c
Void _ init trap_init (void)
{
Set_trap_gate (0, & divide_error );
Set_intr_gate (1, & debug );
Set_intr_gate (2, & nmi );
// System interrupt door
Set_system_intr_gate (3, & int3);/* int3-5 can be called from all */
// System Gate
Set_system_gate (4, & overflow );
Set_system_gate (5, & bounds );

Set_trap_gate (6, & invalid_op );
Set_trap_gate (7, & device_not_available );
Set_task_gate (8, GDT_ENTRY_DOUBLEFAULT_TSS );
Set_trap_gate (9, & coprocessor_segment_overrun );
Set_trap_gate (10, & invalid_TSS );
Set_trap_gate (11, & segment_not_present );
Set_trap_gate (12, & stack_segment );
Set_trap_gate (13, & general_protection );
Set_intr_gate (14, & page_fault );
Set_trap_gate (15, & spurious_interrupt_bug );
Set_trap_gate (16, & coprocessor_error );
Set_trap_gate (17, & alignment_check );
# Ifdef CONFIG_X86_MCE
Set_trap_gate (18, & machine_check );
# Endif
Set_trap_gate (19, & simd_coprocessor_error );

Set_system_gate (SYSCALL_VECTOR, & system_call );
}

2.4.2 initialize the interrupt description table
The final initialization of the interrupt description table is completed in start_kernel () in init/main. c. Asmlinkage void _ init start_kernel (void)
{
// Trap gate Initialization
Trap_init ();
// Interrupt gate Initialization
Init_IRQ ();
// Soft Interrupt Initialization
Softirq_init ();
}

The interrupt door is set in init_IRQ (), as follows: // In arch/i386/kernel/i8259.c
Void _ init init_IRQ (void)
{
// Call init_ISA_irqs
Pre_intr_init_hook ();
// Set the interrupt door
For (I = 0; I <(NR_VECTORS-FIRST_EXTERNAL_VECTOR); I ++ ){
Int vector = FIRST_EXTERNAL_VECTOR + I;
If (I> = NR_IRQS)
Break;
// Skip the system call Vector
If (vector! = SYSCALL_VECTOR)
Set_intr_gate (vector, interrupt [I]);
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.