Linux interrupt-analysis of the interrupt principle

Source: Internet
Author: User
Interrupt is an important technology in the development of computers. its appearance largely frees the CPU and improves the execution efficiency of the CPU. Where an interruption occurs

Principle of interruption

Preface:

Interruption is an important technology in computer development. Its appearance has largely liberated the CPU and improved the execution efficiency of the CPU.

Before the interruption occurs, the CPU uses the polling method for the IO service, which makes the CPU tangle on a certain IO and waits for its response. if it does not respond, the CPU keeps waiting. In this way, other IO ports are waiting for the CPU service. If an IO has important or emergency affairs, the CPU will not be able to respond to this IO.

To solve this tangled problem, ------> There was an interruption.

The main advantage of interrupt control is that it responds only when the I/O interface needs services, so that the CPU can do its own thing calmly, only when the IO port is required can it be responded. At the same time, the interrupt priority is also designed to handle some urgent events.

I. basic interrupt knowledge

1. concepts of interruption:

The so-called interruption refers to the process in which the CPU is interrupted due to the pre-arrangement of the program or internal and external events during the normal running of the program, and is switched to the program in which the program is interrupted. These events that cause Program interruption are called the interruption source.

In fact, from the perspective of physics, interruption is an electrical signal generated by hardware devices and directly sent to the input pin of the interrupt controller (such as 8259A, then the interrupt controller sends the corresponding signal to the processor. Once the processor detects this signal, it will interrupt the work it is currently processing and then process the interruption. After that, the processor will notify the OS that an interruption has occurred. In this way, the OS can properly handle this interrupt. Different devices have different interruptions, and each interruption is identified by a unique number. these values are generally called the interrupt request line.

2. how does the CPU identify an interruption?

In Intel X86, vector interrupt 256 is supported. in order for the processor to enable other types of interrupt sources, serial numbers are provided for them -----> called interrupt vectors.

3. how are these interrupt vectors allocated in Linux:

0 ~ The vectors of 31 correspond to abnormal and unshielded interruptions (these also belong to vector interruptions or internal interruptions. the feature of vector interruptions is a one-to-one ing. an interrupt vector corresponds to an interrupt processing routine)

No. 32 ~ The 47 vector (that is, the interrupt caused by the IO Device) is allocated to the blocked interrupt. (This kind of interrupt is also a non-vector interrupt or external interrupt, which is often described in the Intel manual. The non-vector interrupt feature can be reflected below .)

48 ~ 255 of the vectors are used to indicate soft interruptions. In Linux, 128 or 0x80 is used for system calling. Therefore, 128 interrupt operations are required to access the kernel space through system calling)

The unshielded interrupt vectors and the abnormal vectors are fixed.

4. differences between exceptions and interruptions:

1> exception: it refers to the internal interruption of the CPU, that is, the exception that occurs when the CPU executes a specific command. An exception is also called a synchronization interruption. Therefore, an interruption occurs only after a command is executed, and an exception cannot occur during command execution.

A. cause:

Program error (eg: Division 0)

Exception conditions that must be processed by the kernel (eg: page missing)

B. exceptions are divided into faults and traps. they neither use the interrupt controller nor are blocked.

About 20 of C. X86 processors are abnormal. The Linux kernel must provide a dedicated exception handler for each exception.

2> interrupt: also known as asynchronous interrupt. Therefore, it is randomly generated by other hardware devices according to the CPU clock signal, that is, the interruption can occur between commands.

A. interruption is divided into external shielded interrupt (INTR) and external unshielded interrupt (NMI)

All interrupt requests from the I0 device cause blocked interruptions.

If a fault is caused by a hardware fault, unshielded interruption occurs.

John Note:

When the CPU executes an exception handling program, it no longer responds to other exceptions or interrupts the request service. if an exception occurs at this time, the CPU cannot respond to it, and its information cannot be lost, what should we do?

This means that the stack is used to push all information into the stack. After the current exception is processed, the information is retrieved from the stack and then the exception is returned. (When multiple unshielded interrupts are generated, the CPU processing method is the same as above)

APIC and 8259A

The implementation of interruption also requires hardware support. how does the hardware support interruption?

1. there are only two external pins available for the CPU interruption on the X86 computer: NMI and INTR.

NMI is an unshielded interrupt, which is usually used for power loss and physical memory parity;

INTR can block interruptions. it can be used to block interruptions by setting the interrupt shielding bit. it is mainly used to receive interrupt signals from external hardware that are transmitted to the CPU by the interrupt controller.

2. interrupt controller

Currently, common interrupt controllers include programmable interrupt controllers 8259A and Advanced Programmable Interrupt Controllers (APIC)

1> 8259A

The Programmable Interrupt Controller is connected by two 8259A external chips in Cascade mode. Each chip can process up to 8 different IRQ (interrupt request lines ). Since the INT output line of the PIC is connected to the IRQ2 pin of the main PIC, the number of available IRQ lines reaches 15.

Let's look at a figure: (for illustration)

A. Level 1 8259A is the master interrupt controller. its second interrupt request input end is connected to the interrupt output end INT of level 2 8259A.

B. Each line connected to the interrupt controller is called a disconnection. To use a central disconnection, you must apply for a central disconnection, that is, IRQ.

So the name of this line is the "?" interrupt number.

The IRQ line is sequentially numbered from 0, so the first IRQ line is IRQ0.

C. What is the relationship between the interrupt vectors mentioned above?

Interrupt vector = interrupt number + 32.

From this equation, we can see that the interrupt vector corresponding to the first line break (IR0) is 32.

We can conclude that:

(1) exceptions and unshielded vectors are internal CPU interruptions

(2) the vector 32-47 corresponds to the external interrupt.

D. Not every device can send an interruption signal to the interruption line. only after it has control of a certain disconnection line can it send a signal to the interruption line.

E.8259A also has an important register-> an 8-bit interrupt shielding register-> which is used to block the interrupt.

Each of the eight-bit interrupt shielding storages corresponds to one of the 8259A. if you want to disable a disconnection, set the corresponding position of the interrupt shielding register to 1. if you want to enable this function, set it to 0.

(PS: As you can see, the interruptions that require the interrupt controller are all external interruptions, that is, the interruptions that can be blocked. Each IRQ corresponds to an interrupt vector. But not every interrupt vector can correspond to an IRQ)

John's note:

Blocking interruption can also be considered from the CPU perspective, that is, clearing the eflag Interrupt flag (IF). when the IF bit is 0, any external IO interrupt requests are prohibited, that is, the disconnection;

F. shared interrupt (a very important concept that will be involved in later programs)

As there are more and more external devices on the computer, 15 disconnection lines are insufficient. Disconnection is a very valuable resource. to make better use of it, you can only apply for occupying an IRQ when the device needs to be interrupted, in addition, in order to interrupt the use of more devices, the shared interrupt mode is adopted when IRQ is applied.

(PS: because there are many external devices, multiple devices can correspond to the same IRQ, that is, the same interrupt vector, and one interrupt vector corresponds to one interrupt processing program, however, an interrupt handler may correspond to many interrupt service routines)

2> Advanced Programmable Interrupt Controller (APIC)

Let's look at the picture first and then say:

1.8259A is only applicable to a single CPU. in order to fully explore the concurrency of the SMP architecture, it is critical to transmit the interruption to each CPU in the system. For this reason, Intel introduced a new component named I/O Advanced Programmable Controller to replace the older 8259A programmable interrupt controller. This component consists of two components: a local APIC, which is used to transmit interrupt signals to a specified processor. for example, a machine with three processors, it must have three local APIC pairs. Another important part is I/O APIC, it mainly collects Interrupt signals from the I/O device and sends signals to the local APIC when those devices need to be interrupted (equivalent to a routing function ), the system can have up to 8 I/O APIC.

2. each local APIC has a 32-bit register, an internal clock, a local scheduled device, and two additional IRQ lines LINT0 and LINT1 reserved for local interruptions. All local APICS are connected to I/O APIC to form a multi-level APIC system.

So how do we know the interrupt controller we use on our machine?

You can view the access command at the terminal: cat/proc/interrupts.

A. If you see a IO-APIC in the list, your system is using APIC.

If you see a XT-PIC, it means your system is using an 8259A chip.

The essential difference between the interrupt mechanism in the 16-bit real address mode and the interrupt mechanism in the 32-bit protection mode is that the interrupt description table is introduced in the protection mode.

In a single processor system, the first column is the interrupt number, and the second column is the number of times the CPU generates the interrupt. The last column is the Russian device name related to the interrupt. This name is provided to the function request_irq () through the devname parameter (this will be explained in the next article)

III. interrupt description table

 

1. why?

In real address mode, the CPU uses the 1 KB space starting from 0 as an interrupt vector table. Each table item 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 consisting of four bytes cannot meet the requirements. In protection mode, the table items in the interrupt vector table are composed of 8 bytes. At this time, he also has a new name ----> Interrupt description Table (Interrupt Descriptor Table, IDT) (PS: A total of 256 descriptors, each 8 bytes, 256*8 is the byte space occupied by the interrupt descriptor. each table item is called a gate descriptor (great descriptor) (in other articles in the interrupt series, we will provide a detailed description of various gate descriptors. all system interruptions must go through these Gate descriptors)

The following figure shows the description:

1> DPL: segment descriptor privilege level

2> offset: the offset of the entry function address.

3> P: indicates whether the segment is in memory.

4> segment selection operator: the code segment selection operator of the entry function

5> D: Flag. 1 indicates 32 bits and 0 indicates 16 bits.

6> xxx: three-digit door type code

Door type characters are mainly divided

A. interrupt gate (interrupt gate): the type code is 110. the interrupt gate contains the separator and intra-segment offset of the segment where the interrupt or exception handling program is located.

When the control enters the interrupt processing program through the interrupt door, the processor clears the IF sign, that is, the disconnection is achieved, thus avoiding the interruption nesting.

The DPL (request privilege level) in the interrupt gate is 0, so the process in the user state cannot access the interrupt gate. All the interrupt handlers used are activated by the interrupt gate and are limited to the kernel state. (Access to the interrupt door is required)

B. The type code of the trap gate (tap gate) is 111. 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.

C. system gate: The Linux kernel is specially set to allow user-state processes to access Intel's trap gate.

The DPL of the system door is 3. A system call enters the kernel through the system Gate.

2. in protection mode, the position of the interrupt descriptor table in the memory is no longer limited to the starting position from address 0, but can be placed in any location in the memory.

1> to implement this function ---> an interrupt descriptor table register IDTR is designed in the CPU to store the interrupt descriptor table at the starting position of the memory.

2> the interrupt description table register (IDTR) is a 48-bit register. Its low 16 is to save the size of the interrupt descriptor table, and the high 32-bit stores the base address of the interrupt description table.

3> view:

The interrupt vector is the index of the interrupt vector table (IDT), and the interrupt vector table exists in a certain location in the memory. The Intel register IDTR records its base address (linear address) and size. The IDT table contains the entry address of the external IO interrupt handler registered in the operating system, and the entry addresses of interrupt and exception handling functions related to the architecture implemented by other operating systems (these addresses are stored in the so-called gate destribtor ). Shows the relationship between INTR and IDT:

After we know the functions and basic settings of the interrupt description table, when will the system initialize the table and how will it be initialized?

First, the Linux kernel initializes the interrupt in the initialization phase of the system, including initializing the programmable controller 8259A, loading the start address of the interrupt descriptor table into IDTR, and initializing each item in the table.

(PS: first, find the interrupt descriptor table through IDTR, and then find the endpoint address of the interrupt handler through IDT)

3. interrupt initialization

1> a user process can send an interrupt request using the INT command. the interrupt request vector is 0 ~ In the range of 255.

So how can we prevent users from using INT commands to simulate illegal interruptions and exceptions?

In this case, DPL takes effect-> set DPL to 0.

2> However, sometimes user processes must be able to use the features provided by the kernel (such as system calls), that is, to enter the kernel state from the user state, in this case, you can set the DPL of the interrupt door or trap door to 3.

3> when the computer is in real mode, the interrupt descriptor table is initialized and used by the BIOS.

But, when you enter the Linux kernel, the interrupt descriptor table is moved to another area of the memory and pre-initialized to enter the protection mode:

Use the assembly command LIDT to initialize the IDTR of the interrupt descriptor table register, that is, set IDTR to 0, and then load the start address of the interrupt descriptor table IDT into IDTR.

4> initialize the interrupt description table

A. First initialization: Use the setup_idt () function to fill in the 256 table items in the interrupt descriptor table, and use an empty interrupt handler when filling. Because there are no interrupt handlers in the initialization phase, use this empty interrupt handler to fill in each table item.

B. second initialization: After the paging function is enabled, the kernel initializes the IDT for the second time.

In this case, replace the empty handler with the actual trap and interrupt handler. Once this process is completed, the IDT contains a dedicated trap door or system door for each exception, and the IDT contains a dedicated interrupt door for each external interrupt.

The initialization of IDT is mentioned above, so let's go recursively and look at how the system sets the IDT table items.

4. setting IDT table items

The IDT table item settings are implemented through the _ set_gate () function.

1> Insert an interrupt door

Call the set_intr_gate (n, addr) function to implement

This function inserts an interrupt gate in the nth table entry of IDT. The segment selection character in the door is set to the segment selection character of the kernel code, the offset is set to the address addr of the interrupt handler, and the DPL field is set to 0.

Analysis parameters:

N: insert an interrupt door in the table items.

Addr: indicates the offset. here, the offset is set to the address addr of the interrupt handler.

Now let's take a deeper look at how it is implemented internally.

[Cpp]View plaincopy
  1. 330 static inline void set_intr_gate (unsigned int n, void * addr) 331 {
  2. 332 BUG_ON (unsigned) n> 0xFF); 333 _ set_gate (n, GATE_INTERRUPT, addr, 0, 0, _ KERNEL_CS );
334} [C-sharp]View plaincopy
  1. 19 # if (_ MIPS_ISA> _ MIPS_ISA_MIPS1) 20
  2. 21 static inline void _ BUG_ON (unsigned long condition) 22 {
  3. 23 if (_ builtin_constant_p (condition) {24 if (condition)
  4. 25 BUG (); 26 else
  5. 27 return; 28}
  6. 29 _ asm _ volatile _ ("tne $0, % 0, % 1" 30: "r" (condition ), "I" (BRK_BUG ));
  7. 31} 32
33 # define BUG_ON (C) _ BUG_ON (unsigned long) (C) 34
(1) we can see that the BUG_ON () function is a function macro, and the system finally calls _ BUG_ON (unsigned long) (C )) the fifth parameter indicates that the IST (Interrupt Stack Table) has three digits, and the IST1-IST7 has seven Stack pointers. [C-sharp]View plaincopy
  1. 371 static inline void set_trap_gate (unsigned int n, void * addr) 372 {
  2. 373 BUG_ON (unsigned) n> 0xFF); 374 _ set_gate (n, GATE_TRAP, addr, 0, 0, _ KERNEL_CS );
375} [C-sharp]View plaincopy
  1. 365 static inline void set_system_trap_gate (unsigned int n, void * addr) 366 {
  2. 367 BUG_ON (unsigned) n> 0xFF); 368 _ set_gate (n, GATE_TRAP, addr, 0x3, 0, _ KERNEL_CS );
369} 370
Related Article

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.