In the computer world, there are interrupts everywhere. No work can be done without interrupts. The entire computer system is driven by interrupts. So what is an interrupt? In simple terms, the CPU stops working on the current task to do something else, and then comes back to the original task. This process is called interruption.

The purpose of this paper is to further uncover the veil of interrupt mechanism, clarify interrupt process, interrupt classification, interrupt descriptor table, interrupt controller, and interrupt process. The detailed mind map is as follows:

  • Public id: Rand_cs

A, interrupt classification

External interrupt

1, can shield interrupt: through INTR line to CPU interrupt request, mainly from external devices such as hard disk, printer, network card, etc. This type of interrupt does not affect system operation and can be handled at any time, or even not handled, so it is called maskable interrupt.

2, non-shielding interrupt: through the NMI line to CPU interrupt request, such as power failure, hardware line failure, etc.. “Unmasked” means not allowed, not recommended, but the problem is too big, cannot be shielded, cannot be shielded.

Note: INTR and NMI are CPU pins

Internal interrupt (soft interrupt, exception)

1, trap: is a kind of intentional, pre-arranged exception event, generally in the writing of the program is deliberately set down the trap instruction, and then execute to the trap instruction, THE CPU will call the specific program for the corresponding processing, after the end of the processing to return to the next instruction of the trap instruction. Such as system call, program debugging functions.

Although we do not seem to have set traps when we write programs, it is because the high-level language we use is too abstracted to see the implementation of the underlying instructions, but in fact there are. For example, in the printf function, the lowest level implementation will have an int 0x80 instruction, which is a trap instruction that uses the 0x80 interrupt to make the system call.

2, fault: fault is caused by the fault of the command is executed, but not the end of the execution, CPU detected a class of unexpected events. When an error occurs, the fault handler handles it. If the error can be corrected, control is returned to the instruction that caused the fault, that is, the CPU re-executes this instruction. An error is reported if it cannot be handled.

A common fault is a missing page, which occurs when the physical page corresponding to the virtual address referenced by the CPU does not exist. Page missing exceptions can be fixed with a special page missing handler that brings the missing physical page back from disk into main memory. And then when the instructions that caused the failure are executed again, they can be executed smoothly.

3. Termination: a fatal error occurs during the execution of the command, which cannot be fixed. The program cannot continue to run, but can only be terminated, usually due to some hardware errors. The termination handler does not return control to the original program, but terminates it directly

Interrupt descriptor table

Interrupt descriptor table is similar to the global description table, and the table stores descriptors. Different from GDT, IDT can store four descriptors: task gate descriptor, trap gate descriptor, call gate descriptor, and interrupt gate descriptor.

We only introduce interrupt gate descriptors here. The four descriptors are similar except for task gate, and interrupt gate is also the most commonly used. For example, Linux system call is realized by using interrupt gate.

Interrupt gate descriptor

Interrupt descriptors are structured as above, with important fields and attributes marked, so it is good to have an understanding, rather than digging into the specific meaning of each bit.

Interrupt vector number

The interrupt vector number is equivalent to the segment selector’s high 13 bits and is used to index the relative interrupt descriptors in IDT, but does not have the corresponding segment selector like structure. (GDT, segment selectors, and segment descriptors can be found in previous articles.)

Part of the interrupt direction scale is shown in the figure below:

The interrupt descriptor list register IDTR

Similar to GDTR, IDTR stores 48 bits of data. The higher 32 bits are the ADDRESS of the IDT, and the lower 16 bits are the limit of the IDT.

Like GDTR, IDTR also has load instructions: lidt m16&32, m is the 48-bit data information, liDT instructions load it into the IDTR register, so that the CPU knows where the IDT is.

Interrupt controller

Each of the peripherals running independently can be an interrupt source and can send interrupt requests to the CPU. In order to facilitate management and reduce the number of pins, the interrupt controller is set up so that all maskable interrupts communicate with the CPU through INTR signal lines.

The more popular interrupt controller is Intel 8259A chip, the following is a brief introduction to 8259A:

cascade

A single 8259A chip has only 8 interrupt request signal lines (IRQ0, IRQ1… , IRQ7), this is not enough, so multiple 8259A chips are used. Combine them in series as shown in the picture below. This combination is called cascading.Only one master slice can be cascaded, and the rest are slave slices. A maximum of nine master slices can be cascaded, that is, a maximum of 64 interrupts can be supported. Why isn’t 8 times 9 72? As can be seen from the figure above, the chip at the back will occupy one IRQ interface of the chip at the front, while the last 8259A is not occupied by others. Therefore, the relationship between the number of 8259A and the number of supported interrupts is 7N + 1.

Some of the 8259A’s registers and features

1, IMR: Interrupt Mask Register, where each bit marks a peripheral, 1 indicates that the peripheral is masked, and 0 indicates that interrupts are allowed.

(2) IRR (An interrupt Request Register) (the bit-value of an interrupt Request peripheral is 1) When there are multiple interrupt requests, the bit bit in the IRR register will be set to 1, which is equivalent to maintaining a queue of interrupt requests.

3. ISR: In_Service Register, which indicates the interrupt service Register. The bit value of the interrupt being processed in ISR is 1.

4, PR: Priority Resolver, which is used to select an IRR with the highest Priority. (A small IRQ interface number has a higher priority.)

Interrupt the process

Interrupt request

1. When the peripheral sends an interrupt signal, the signal is sent to 8259A;

2. 8259A checks whether the signal from this IRQ is shielded in the IMR register. If the corresponding bit in the IMR register is 1, it means that the interrupt represented by IRQ is shielded, and the interrupt signal is discarded.

3. The PR priority adjudicator picks an interrupt with the highest priority from the IRR register, and 8259A sends INTR signal to the CPU.

Interrupt response

1. CPU will know that there is a new interrupt after receiving INTR signal, and then send an interrupt reply signal to 8259A after executing the current instruction.

2. After 8259A receives the reply signal, it sets the selected interrupt with the highest priority to the corresponding bit 1 in the ISR register, indicating that the interrupt is being processed. At the same time, it sets the interrupt to the corresponding bit 0 in the IRR register, which is equivalent to removing the interrupt from the interrupt request queue.

3. The CPU sends INTR signal to 8259A again, indicating that it wants to obtain the interrupt vector number.

3. 8259A sends interrupt vector number to CPU through data bus, interrupt vector number = start vector number + IRQ interface number. Generally, the start vector number is 32.

Protect the site – stack

1. CPU obtains the interrupt descriptor from IDT according to the interrupt vector number and compares the DPL in the selector with the current privilege level CPL. If the privilege level changes, it needs to switch the stack. (Different privilege levels have different stacks, for example, Linux uses privilege levels 0, 3, there are two stacks, one kernel stack, one user stack)

2. Then the processor temporarily saves the current old stack SS and ESP values, and loads the same stack information as the DPL privilege from TSS (each task has a TSS structure, which stores the SS and ESP values of different privilege stacks) into the SS and ESP registers. The values of SS and ESP in the old stack are pushed into the new stack. If the privilege level does not change, skip this step.3. Press the program status information, that is, the EFLAGS register3. Press the breakpoint, that is, return the address, that is, the CS, EIP value of the current task.4, if the interrupt has an error code, press the error code

Locate the interrupt service routine

Directly on the flow chart:The specific steps are as follows:

1, according to the interrupt vector number to IDT index interrupt descriptor, specific operation: take out IDT address in IDTR, plus interrupt vector number * 8, the address points to the desired interrupt descriptor.

2, according to the segment selector in the interrupt descriptor to index the segment descriptor in GDT, the specific operation: extract the GDT address in GDTR. Add the segment selector height 13 bits * 8, and the resulting address is the segment base address of the segment where the interrupt handler resides.

3. The segment base address obtained in the previous step plus the intra-segment offset in the segment descriptor becomes the address of the interrupt service routine.

Interrupt handling procedure

The actual process of handling an interrupt is to execute an interrupt handler, which Linux divides into two parts: those that need urgent action and immediate execution are placed in the top half, and those that need less urgent action are placed in the bottom half.

This leads to the problem of switch interrupts. Open interrupt, that is, IF position 1 of EFLAGS, indicates that response interrupt is allowed. Off interrupts, i.e., IF position 0 of EFLAGS, indicates that response interrupts are not allowed.

1, the upper part is urgent, the part that needs to be executed immediately, so it should be executed under the state of shutdown interruption.

2, and the lower part is not so urgent, under the condition of open interrupt, if there is a new interrupt occurs at this time, the current interrupt processing program will replace the CPU, THE CPU will find another time to reschedule, complete the entire interrupt processing program.

Interrupt return — out of the stack

Interrupt return is the process of stepping off the stack, which pops up the information pushed in step 3 protection field.

1. Error codes are displayed.

2. At this time, the top pointer ESP should point to EIP_old, and the information in the rest of the stack will be displayed with iRET instruction. When the CPU executes the IRET instruction, it will check again and compare whether the privilege level is changed.

EIP_old, CS_old

4. If the privilege level changes, load ESP_old and SS_old into ESP and SS registers.

At this point, the interrupt has been returned and the interrupt has been handled.

The above interrupt pressing is an automatic part of the CPU. The actual interrupt processing will not only save this bit of information. The formal saving context operation will be performed in the interrupt handler.

And the interruption of the process is based on the data I according to own understanding is divided into six steps, each step and there are a lot of micro operation, probably with some of the books information, divided into different steps, even a minor operation order is different, for example when the interrupt processing interrupt, I looked through many data and books, account must have difference. The implementation of interrupts varies from operating system to operating system, but in general, the steps described above can be slightly different, but it does not affect our understanding of the interrupt process.

Interrupts are an important mechanism of the operating system. Without interrupts, the operating system cannot do anything, cannot input or output, cannot manage hardware resources, and cannot provide services to upper-layer applications. And the operating system itself is like an endless loop, waiting for events to happen and then providing services to solve the problem. The occurrence and processing of this event is controlled by the interrupt mechanism, so the interrupt for the operating system has a decisive role, and we also need to understand the interrupt, clear the interrupt process.

Original is not easy, like this article friends also please like to support it again!