Linux Kernel Core Chinese Manual (7) - Interrupt and Interrupt Processing

xiaoxiao2021-03-06  42

Interrupts and Interrupt Handling (Interrupts and Interrupt Processes) This chapter explores how Linux core handles interrupts. Although the core has a general mechanism and interface of the interrupt, most interrupt processing details are related to the architecture. Linux uses a large number of different hardware to complete many different tasks. Display device drive displays, IDE devices drive disks, and more. You can drive these devices in synchronization, that is, you can issue a request to perform some operations (such as writing a memory to disk) and then wait for the end. This way, although it works, it is very efficient, the operating system will spend a lot of time when it is waiting for each operation, "busy doing nothing". A good, more effective way is to make a request and then make other more useful things, and then be interrupted when the device completes the request. In this scenario, there may be many devices in the system at the same time at the same time. Let the device interrupt the CPU current work must have some hardware support. Most, if not all, the general purpose processor uses a similar method such as Alpha Axp. Circuits of some physical pins of the CPU will change the voltage (e.g., from 5V to -5V), let the CPU stop working, and start the special code of the processing interrupt: interrupt processing code. One of these pins may be connected to an internal mode, each of each 1000, receives an interrupt, other devices that may be connected to the system, such as the SCSI controller. The system typically uses an interrupt controller to put the interrupts of the device together, then transfer the signal to a single interrupt pin of the CPU. This saves the interrupt discipline of CPU, but also brings flexibility to the design system. The interrupt controller has mask and status registers for controlling these interrupts. The bit of the setting mask register can allow and disable the interrupt, and the status register returns the current interrupt in the system. Interrupts in some systems may be hard-connected, such as internal clocks of real-time clocks, may be permanently connected to the third pin of the interrupt controller. However, other pin connections may be determined by what control cards are inserted in a specific ISA or PCI slot. For example, the fourth pin of the interrupt controller may be connected to the PCI slot 0, which may have an Ethernet card a certain day, and then a SCSI control card later. Each system has its own interrupt transit mechanism, and the operating system must be flexible to handle it. Most modern general purpose microprocessors handle interrupts in the same way. When the hardware interruption occurs, the CPU stops it running, jumps to a location where the memory is running, here or the interrupt processing code or the command to jump to the interrupt processing code. This code is usually working in a special mode of the CPU: interrupt mode, usually, other interrupts in this mode cannot be generated. There are also exceptions here: Some CPUs will interrupt the level, and higher level interrupts can occur. This means that the first-level interrupt handler must be very careful. Interrupt handles usually have their own stacks to store the execution status of the CPU (all universal registers and contexts of the CPU) and process the interrupt. Some CPUs have a set of registers existing in interrupt mode, and interrupt processing code can use these registers to store most of the context information they need to be saved. When the process is overtered, the status of the CPU is restored, the interrupt ends. The CPU will continue to do what it do before interruption. Important interrupt handles must be as valid as possible, usually the operating system cannot often block interrupts for a long time.

7.1 ProgramMable Interrupt Controllers The system designer can use the interrupt architecture they want to use, but IBM PC uses Intel 82C59A-2 CMOS programmable interrupt controller or its derivative. This controller is used in the initial PC. It can be programmed by register, which is well known in the ISA address space. Even modern logical chipsets retain an equivalent register in the same location of ISA memory. Non-Intel systems, such as Alpha AxP PCs are not subject to these system, usually using different interrupt controllers. Figure 7.1 shows two 8-bit controllers in series: each has a mask and an interrupt status register, PIC1, and PIC2. The mask register is located at address 0x21 and 0xA1, and the status register is located at 0x20 and 0xA0. A special bit write 1 in the mask register allows an interrupt to write 0 can disable it. So the bit 3 is written 1 allows interrupt 3, and write 0 will prohibit it. Unfortunately, it is also annoying), the interrupt mask register can only be written, you can't read it back to the value you wrote. This means that Linux must keep a local copy for the mask (MASK) register it set. It modifies these saved masks in the interrupts allowed and prohibited routines, and writes the entire mask to the register each time. When an interrupt signal is generated, the interrupt handler reads two interrupt status registers (ISR). It treats 0x20 ISR as the 8th bit of the 16-bit interrupt register, and ISR in 0xA0 is considered to be 8 bits. Therefore, the interruption of the first bit of the ISR of 0xA0 is considered to be interrupted 9. The second bit of PCI1 is not available because it is used as an interrupt of the series PIC2, ​​and any PIC2 interrupt will cause the second position of PIC1. 7.2 Initializing The Interrupt Handling Data Structure (Initialization Interrupt Processing Data Structure) When the device driver requires the control system's interrupt to establish a core interrupt processing data structure. To do this, the device driver uses a range of Linux core services to request an interrupt, allowing it and disable it. These device drivers call these routines to register their interrupt processing routines. See Arch / * / kernel / Irq.c request_irq (), enable_irq () and disable_irq () PC architecture In order to facilitate the convenience of fixing some interrupts, the driver only needs to simply request its interrupt when initialization. The floppy device driver is like this: it always requests interrupt 6. But it is also possible that a device driver does not know what is interrupted. This is not a problem with the PCI device driver because they always know their interrupt numbers. Unfortunately, there is no simple way to find their interrupt numbers for ISA devices. Linux allows the device driver to explore their interrupts to solve this problem. First, the device driver allows the device to generate an interrupt, and all unassigned interrupts in the system are allowed. This means that the interruption of the device waiting processing will now be passed through the programmable interrupt controller. Linux reads the interrupt status register and then returns its content to the device driver. The result of non-0 indicates that one or more interrupts occurred in the exploration. The driver now shuts down the probe and disables all bits allocated. If the ISA device driver successfully found its IRQ number, it can request to control it in the same way. See Arch / * / Kernel / Irq.c Irq_Probe_ * () PCI system is more dynamic than the ISA system. The interrupt of the ISA device typically sets with jumpers on the hardware device, which is fixed for the device driver.

Conversely, the interrupt of the PCI device is assigned by the PCI BIOS or the PCI subsystem when the system is started. Each PCI device can use one of four interrupt pins: A, B, C, C, C, and D. At this time, the equipment is determined, most devices default to interrupt pin A. Each PCI interrupt line (Interrupte line) A, B, C, and D are turned to the interrupt controller. Therefore, the pin A of the slot 4 may go to the 6th pin of the interrupt controller, and the pin B of the slot 4 may go to the pin 7 of the interrupt controller, and so on. How PCI interrupts are forwarded (routing Route) is completely related to the system, and there must be some understanding of this PCI interrupt routing topology. On the Intel PC, this is the system BIOS code that is started. But for systems with no BIOS (such as Alpha AxP systems), Linux makes this setting. The PCI setting code writes the pin number of the interrupt controller to the PCI configuration header of each device. It uses the PCI interrupts it knows with topologies and PCI slots and it is using the PCI interrupt pin to determine the interrupt pin (or IRQ) number. The interrupt pin used by the device is determined and placed in a domain of the PCI configuration header. It writes this information to an interrupt line (this is reserved for this purpose). When the device driver is running, it reads this information and uses it to control the interrupt to the Linux core. See many PCI interrupt resources in the Arch / Alpha / Kernel / Bios32.c system. For example, when using a PCI-PCI bridge. The number of interrupt sources may exceed the number of pins of the system's programmable interrupt controller. In this case, the PCI device can share an interrupt: a pin on the interrupt controller receives an interrupt from more than one PCI device. Linux allows the first source requesting an interrupt source claiming whether it can be shared, so that it supports interrupt sharing. The shared interrupt result is that an entry in the IRQ_Action vector table can point to the data structure of several IrqAction. When a shared interrupt occurs, Linux calls all interrupt handler for this source. All device drivers that can share interrupts (both PCI device drivers) must be called when there is no interrupt service. 7.3 Interrupt Handling Linux Interrupt Processing Subsystem is to transfer interrupts to the correct interrupt processing code segment. This code must understand the interrupt topology of the system. For example, if the floppic drive controller is interrupted at the pin 6 of the interrupt controller, it must be able to identify the interrupt from the floppy drive and transfer it to the interrupt handler code of the software drive device driver. Linux uses a series of data structures that contain the address of the routine that handles the system interrupt. These routines belong to the device driver of the device in the system, each device driver must be responsible for requesting the interrupt it wants when the driver is initialized. Figure 7.2 Show Irq_Action is a vector table for pointer to the IRQAction data structure. Each IRQAction data structure includes information of this interrupt handler, including the address of the interrupt processing routine. The number of interruptions and how to handle different systems are different, usually, between different systems, Linux interrupt processing code is related to the architecture. This means that the size of the IRQ_Action vector table depends different from the number of interrupt sources.

转载请注明原文地址:https://www.9cbs.com/read-51935.html

New Post(0)