Windows interrupts the Thing

Source: Internet
Author: User
Tags apc

The concept of interruption is often not unfamiliar to the core research, and often we are exposed to many of the terminology associated with interrupts, categorized by software and hardware:

Hardware CPU Related:

IRQ, IDT, Cli&sti

Software operating system Related:

APC, DPC, IRQL

It has been smattering to interrupt this part of the content, how the operating system and CPU work together is also very vague. Recently spent a bit of time to carefully comb this piece of knowledge, improper, but also please master pointed out, first thanked!

This article is intended to answer the following questions:

What is the relationship between 1.IRQ and IRQL?

2.Windows is how to IRQL this set of interrupt mechanism on software level.

Both 3.APC and DPC are software interrupts, so where are the processing routines in the corresponding IDT table entries, since they are interrupts?

0x00 Intel 80386 interrupt of the processor

First, let's forget about Windows, starting with the first 80386 processors, and see how Intel designed it to handle interrupts.

Let's take a look at what this CPU, which was born in 1985, looks like:

Look at those protruding pins, here is the pin callout diagram:

Note the two pins labeled with the red circle, which are the two pins that the 80386 processor has left out for interrupts. Where Intr is a shielded interrupt input port, NMI is an unshielded interrupt input port.

So how is the interrupt entered into the processor? So many external devices, which have only one pin (for the moment only a shielded interrupt is considered), there is a need to equip the CPU with a management interrupt Secretary-the programmable Interrupt controller pic. What kind of work does the Secretary need to do? Interrupts from the external device go from it to the central processing unit, so it is responsible for receiving the interrupt signal from the peripheral and initiating an interrupt request to the CPU based on the priority level. The first pic character was a chip codenamed 8259A that was playing, and the cargo grew like this:

Here is the pin diagram for it:

Where Ir0-ir7 a total of 8 pins are responsible for connecting external devices, 8259A pic Each IR port is connected with an IRQ line to receive the interrupt signal of the peripheral. int is responsible for connecting the INTR pin of the CPU to initiate an interrupt request to the CPU. Usually, the use of two 8259A chip Cascade, a connection to the CPU, called the main chip, and the other one connected to the main pic IR2 pin, called from the chip, so that a total of 8+7=15 peripherals can be connected. As shown in the following:

In 8259A, by default the priority is the maximum interrupt request priority of the primary IR0, the lowest IR7 of the primary slice, and the priority of all interrupt requests from the slice ir0-7 equal to IR2. So the priority of the IRQ line is from high to low order of irq0,irq1,irq8-15,irq3-7. This is the default and can be changed programmatically.

There are several important registers inside the 8259A chip:

Interrupt Request Register: Irr,8bit, corresponding to IR0-IR7, when the corresponding PIN generates an interrupt signal, the bit position is 1.

Interrupt Service Register: isr,8bit, corresponding to IR0-IR7, when the corresponding PIN interrupt is being processed by the CPU, the bit position is 1.

Interrupt screen Register: imr,8bit, corresponding to the IR0-IR7, when the corresponding bit is 1 o'clock, the interrupt signal generated by shielding the PIN is indicated.

There is also an interrupt priority judgment: PR, when the interrupt pin has a signal, combined with the interrupt generated by the IRQ number and the ISR recorded in the current processing of the interrupt information, according to the priority to determine whether to report the new interrupt signal to the CPU, so as to generate interrupt nesting.

Here are the peripherals connected to each of the 15 IRQ lines:

Now let's take a look at how this secretary works in coordination with the CPU.

Now suppose we hit a keyboard button, the keyboard has an interrupt event generated, this event through the IRQ1 this line tells the main pic, the main pic after some internal judgment processing through an int send an electrical signal to the CPU side of the intr. After executing the current instruction, the CPU checks that the INTR has a signal, indicates that there is an interrupt request, and then checks if the eflags is not zero, indicates the current allowable interrupt, sends the signal to PIC's-inta, tells it to send the vector number of this interrupt. After the master pic receives the signal on the-inta pin, it outputs the interrupt vector number to the data bus via the D0-D7 pin, which simplifies the interactive process and actually sends two of the INTA signal. After the CPU gets this number, it can be processed from IDT looking for an interrupt service routine (ISR), which we all know later.

How does the interrupt vector number in pic come from? How does each IRQ correspond to the individual items in IDT? This is determined by the programmability of the interrupt controller.

Pic is all called a programmable interrupt controller, so what is its programmability? Reference 2The article "i8259a Interrupt Controller Analysis one " is described in more detail, including the program specifies the interrupt vector number of the interrupt in the IDT table that corresponds to the IRQ line of the master/slave chip, the interrupt mode of the 8259A interrupt controller, Priority mode, interrupt nesting, interrupt masking, interrupt termination, and so on, can be specified by the operating system programming. The specific programming format in reference 3"i8259a Interrupt Controller Analysis II" is illustrated in the article.

Back to the previous question, how interrupts on the IRQ line correspond to the entries in IDT, when the operating system is initialized, by programming the 8259A chip (read/write I/O port), it will specify the starting vector number of the PIC chip, and require a low three bit to 0, the starting vector number is aligned by 8, so the reason is that When an interrupt occurs, the lower three bits are automatically populated with the corresponding IRQ number, which can be added directly to the data bus and then taken by the CPU with the starting vector number. specifically to Windows, the system initializes the PIC programming as: Specifies that the primary slice's starting interrupt vector number is 0x30, specifying the starting interrupt vector number from the slice as 0x38. This way, 15 peripherals connected by the interrupt controller will be flattened into the range of 0x30-0x40 in IDT. The Windows kernel starts the initialization process using the hal! Halpinitializepics Programming the 8259A chip, the code in the ReactOS is as follows:

Where 0x20,0x21 is the IO port of the main piece, 0XA0,0XA1 is the IO port from the slice:

Primary_vector_base is defined as:

The specific 8259a programming method is to read and write IO port, set the corresponding control command, without in-depth study. Let's look at what is specified when Windows programming 8259a.

1, specified the main slice of the mode of operation is cascaded, interrupt mode for the signal edge trigger

2. The interrupt vector mapping for the main IRQ is specified base address: 0x30

3, specified the main piece of the Cascade mode for the use of their own IRQ2 this pin

4, specified the main slice of the operating mode of 80x86 mode, the end of the interrupt mode is the normal end

5, specified from the working mode of the slice cascade, interrupt mode for the signal edge trigger

6, specified the interrupt vector from the chip IRQ map base: 0x38

7, specified from the working mode of the film cascade mode for the IRQ2 of the main piece of this pin

8, specified from the working mode of the slice is 80x86 mode, the end of the interrupt mode is the normal end pattern

at this point we can know that in using 8259A on the computer that interrupts the controller, IRQ The line-connected that the a peripheral can be shielded interrupts are mapped by the operating system linearly to the IDT a range segment in the. in Windows is the 0x30-0x40(PS: in Linux in is 0x20-0x2f ), the interrupt controller is specified as an edge trigger, and the end mode is the normal end mode (which requires CPU side tells interrupt processing there is no end and set the corresponding bit bit, cannot be set automatically).

0x02 8259a on the Windows IRQL

Let's take a look at IRQL.

From the front we see that the hardware level has provided a good support for the processing of interrupts, the need for the operating system is also two points: first, the initialization of the PIC programming to set its working mode and the IRQ mapping, so that these interrupts correspond to the various items in IDT, and secondly, Implement the interrupt service routines in these IDT. It seems to be enough, what is the set of IRQL that Windows has come up with?

Look at the definition of IRQL in the book "Windows Internals":

Write-driven often comes into contact with the concept of IRQL, which implements the interrupt priority system in Windows, where high-priority interrupts are always prioritized, while low-priority interrupts have to wait for high-priority interrupts to be processed. Software virtual out of this mechanism how to control the priority of the hardware? How is this implemented?

To solve two problems first:

1. What is the relationship between IRQ and IRQL?

2. After using KERAISEIRQL to elevate the current IRQL, why is it guaranteed not to be interrupted by a low-priority interrupt?

For the first problem, IRQL=0X27-IRQ is a linear relationship in a computer that uses a 8259a interrupt controller.

On the second question, the book "Windows Internals" answers:

Let's look at the implementation of windows in detail:

IRQL is a completely virtual concept, windows in order to implement this virtual mechanism, completely virtual an interrupt controller, it in the KPCR:

+0x024 Irql:uchar//IRQL

+0x028 irr:uint4b//virtual Interrupt Request Register

+0X02C irractive:uint4b//virtual Interrupt in service register

+0x030 idr:uint4b//Virtual Interrupt screen Register

As mentioned in the first section above, 15 interrupt sources connected by two 8259a chips are mapped to a range in the processor IDT, specifically windows, in the 0x30-0x40 range. The interrupt descriptor described in these 15 IDT interrupt-processing routines (ISR) differs from the kitrap0e corresponding to the KiTrap03 and int 0e corresponding to int 3, whose ISR points to the dispatchcode of the respective interrupt object Kinterrupt. Here is the definition of this structure:

 typedef struct   _kinterrupt {CSHORT Type;    CSHORT Size;    List_entry Interruptlistentry;    Pkservice_routine Serviceroutine;    PVOID Servicecontext;    Kspin_lock SpinLock;    ULONG TickCount;    Pkspin_lock Actuallock;    PVOID dispatchaddress;    ULONG Vector;    KIRQL IRQL;    KIRQL SYNCHRONIZEIRQL;    BOOLEAN Floatingsave;    BOOLEAN Connected;    CHAR number;    UCHAR Sharevector;    Kinterrupt_mode MODE;    ULONG Servicecount;    ULONG Dispatchcount; ULONG dispatchcode[ 106  ];} Kinterrupt,  *pkinterrupt; 

Dispatchcode inside the code is based on a template, these ISR processing starts and KiTrap03 these, the first will create a trap frame, and then get their own Kinterrupt object address, after getting these two parameters, Start using Kiinterruptdispatch or Kichaineddispatch (if more than one KINTERRUPT structure is registered with the interrupt to make the list use this function) to interrupt dispatch. In these two specific dispatch will call Halbeginsysteminterrupt first, then will perform the corresponding interruption of the actual processing work, and finally execute the Halendsysteminterrupt to complete the interrupt processing. Let's take a look at these two functions.

Booleanhalbeginsysteminterrupt (    in KIRQL Irql-    CChar Vector, out    pkirql OLDIRQL);

The input parameter IRQL indicates that the interrupt corresponding to this occurrence of the irql,vector represents the interrupt vector number, as described above, both of which are dispatchcode removed from their own Kinterrupt object.

Halbeginsysteminterrupt internally uses the IRQL parameter in a table to distribute, the table in addition to the individual functions (in fact, only a layer of judgment), the other table items are consistent, In ReactOS, called Halpdismissirqgeneric, the function calls its underlined version of _halpdismissirqgeneric directly instead. This is the core of the IRQL priority implementation. This function is not long, the following is the code in the ReactOS (in the Windows2000 code is the assembly form is not as intuitive as the C language used in ReactOS, so the ReactOS code to explain):

First, to judge the occurrence of the interrupt corresponding to the IRQL and the current processor (KPCR) in the comparison of IRQL, if the current processor is greater than the IRQL, it represents a higher priority interrupt, when the KPCR in the set IRQL for this new higher value, followed by the return of true, Indicates that this interrupt request needs to be processed. If it is not larger than the current processor IRQL, the first time the interrupt record to the KPCR in the virtual Interrupt Controller IRR value, and then directly through the Kii8259masktable table select the current processor IRQL the corresponding shield code written to the PIC, To block those IRQL that are lower than themselves, followed by false, indicating that the interrupt request is not processed. Why not set the mask on the new IRQL of the processor? "Windows Internals" explains this:

The return value of the halpdismissirqgeneric will be used directly as the return value of the halbeginsysteminterrupt. Take the interrupt dispatch function Kiinterruptdispatch as an example to see how it uses this return value:

As you can see, if Halbeginsysteminterrupt returns false, it directly causes this interrupt processing to end prematurely. The true interrupt processing routine continues only if Halbeginsysteminterrupt returns True. Finally, the situation calls Kiexitinterrupt to end the interrupt processing process and take a look at this function. In combination with the code of Kiinterruptdispatch, it can be seen that the following if condition will be established only if Halbeginsysteminterrupt returns True, thus entering the halendsysteminterrupt.

Finally take a look at Halendsysteminterrupt, mentioned earlier if the occurrence of the interrupt corresponding to the IRQL lower than the processor IRQL, it will not execute its ISR, but will be recorded in the KPCR of the virtual Interrupt controller IRR, wait until the processor finished high IRQL task , when the halendsysteminterrupt, it will reduce the processor IRQL and reset the pic interrupt mask, it is important to check the IRR record, if there is less than the lower IRQL record, then dispatched the interrupt.

Finally, summarize the IRQL of windows in the computer using the 8259A Interrupt controller.

First, the system starts with a 8259a chip programming, sets its mode of operation, and maps 15 interrupt sources (IRQ) to 0x30-0x40 in IDT.

Second, Windows itself defines a IRQL concept called interrupt request level to describe the priority level of interrupts, IRQL is a DWORD, a total of 32 levels, and Windows uses a simple linear relationship to map IRQ and IRQL:IRQL=27-IRQ.

Thirdly, each ISR of the interrupt descriptor for the 0x30-0x40 that is mapped to the interrupt request points to a dispatchcode in a kinterrupt structure. This section of the Dispatchcode uses an interrupt dispatch function Kiinterruptdispatch or Kichaineddispatch to interrupt dispatch.

IV, the dispatch process is: First use Halbeginsysteminterrupt to the IRQL of this interruption to determine whether to deal with this interruption, if not necessary, set the interrupt Controller shield code, to prevent further interruption, At the same time, this interrupt is registered in the virtual Interrupt controller IRR in KPCR. If necessary, raise the IRQL to perform the actual processing routine of the interrupt, use Halendsysteminterrupt to reduce IRQL after execution, and then check that IRR has not logged the interrupts that were not processed to be processed at this time.

0x03 into the Pentium era-- APIC

We'll talk later.

Windows interrupts the Thing

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.