| Interrupt handling depends on the type of interrupt. three main classes of interrupts: | |||||||
| I/O interrupts | |||||||
| An I/O device requires attention; the corresponding interrupt handler | |||||||
| must query the device to determine the proper course of action. | |||||||
| Timer interrupts | |||||||
| Some timer, either a local APIC timer or an external timer, has issued an interrupt; | |||||||
| this kind of interrupt tells the kernel that a fixed-time interval has elapsed. | |||||||
| These interrupts are handled mostly as I/O interrupts; | |||||||
| Interprocessor interrupts | |||||||
| A CPU issued an interrupt to another CPU of a multiprocessor system | |||||||
| I/O Interrupt Handling | |||||||
| Interrupt handler flexibility is achieved in two distinct ways | |||||||
| IRQ sharing | |||||||
| IRQ dynamic allocation | |||||||
| Linux divides the actions to be performed following an interrupt into three classes: | |||||||
| Critical | |||||||
| Noncritical | |||||||
| Noncritical deferrable | |||||||
| all I/O interrupt handlers perform the same four basic actions: | |||||||
| 1. Save the IRQ value and the register's contents on the Kernel Mode stack. | |||||||
| 2. Send an acknowledgment to the PIC that is servicing the IRQ line, | |||||||
| thus allowing it to issue further interrupts | |||||||
| 3. Execute the interrupt service routines (ISRs) associated with all the devices that share the IRQ. | |||||||
| 4. Terminate by jumping to the ret_from_intr( ) address. | |||||||
| Interrupt vectors | |||||||
| physical IRQs may be assigned any vector in the range 32-238. | |||||||
| However, Linux uses vector 128 to implement system calls. | |||||||
| The IBM-compatible PC architecture requires that some devices | |||||||
| be statically connected to specific IRQ lines. In particular: | |||||||
| · The interval timer device must be connected to the IRQ 0 line | |||||||
| · The slave 8259A PIC must be connected to the IRQ 2 line | |||||||
| (although more advanced PICs are now being used, Linux still supports 8259A-style PICs) | |||||||
| · The external mathematical coprocessor must be connected to the IRQ 13 line | |||||||
| · In general, an I/O device can be connected to a limited number of IRQ lines. | |||||||
| There are three ways to select a line for an IRQ-configurable device: | |||||||
| · By setting hardware jumpers (only on very old device cards). | |||||||
| · By a utility program shipped with the device and executed when installing it. | |||||||
| Such a program may either ask the user to select an available IRQ number | |||||||
| or probe the system to determine an available number by itself | |||||||
| · By a hardware protocol executed at system startup. | |||||||
| Peripheral devices declare which interrupt lines they are ready to use; | |||||||
| IRQ data structures | |||||||
| irq_desc_t | |||||||
| irq_desc | |||||||
| /* | |||||||
| * Interrupt controller descriptor. This is all we need | |||||||
| * to describe about the low-level hardware. | |||||||
| */ | |||||||
| struct hw_interrupt_type { | |||||||
| const char * typename; | |||||||
| unsigned int (*startup)(unsigned int irq); | |||||||
| void (*shutdown)(unsigned int irq); | |||||||
| void (*enable)(unsigned int irq); | |||||||
| void (*disable)(unsigned int irq); | |||||||
| void (*ack)(unsigned int irq); | |||||||
| void (*end)(unsigned int irq); | |||||||
| void (*set_affinity)(unsigned int irq, cpumask_t dest); | |||||||
| }; | |||||||
| typedef struct irq_desc { | |||||||
| unsigned int status; | /* IRQ status */ | ||||||
| hw_irq_controller *handler; | |||||||
| struct irqaction *action; | /* IRQ action list */ | ||||||
| unsigned int depth; | /* nested irq disables */ | ||||||
| unsigned int irq_count; | /* For detecting broken interrupts */ | ||||||
| unsigned int irqs_unhandled; | |||||||
| spinlock_t lock; | |||||||
| } ____cacheline_aligned irq_desc_t; | |||||||
| /* | |||||||
| * IRQ line status. | |||||||
| */ | |||||||
| #define IRQ_INPROGRESS | 1 | /* IRQ handler active - do not enter! */ | |||||
| #define IRQ_DISABLED | 2 | /* IRQ disabled - do not enter! */ | |||||
| #define IRQ_PENDING | 4 | /* IRQ pending - replay on enable */ | |||||
| #define IRQ_REPLAY | 8 | /* IRQ has been replayed but not acked yet */ | |||||
| #define IRQ_AUTODETECT | 16 | /* IRQ is being autodetected */ | |||||
| #define IRQ_WAITING | 32 | /* IRQ not yet seen - for autodetection */ | |||||
| #define IRQ_LEVEL | 64 | /* IRQ level triggered */ | |||||
| #define IRQ_MASKED | 128 | /* IRQ masked - shouldn't be seen again */ | |||||
| #define IRQ_PER_CPU | 256 | /* IRQ is per CPU */ | |||||
| void disable_irq(unsigned int irq) | |||||||
| void enable_irq(unsigned int irq) | |||||||
| void __init init_IRQ(void) | |||||||
Understanding the linux kernel-ch4-Interrupt Handling
最新推荐文章于 2012-08-13 10:16:52 发布
本文详细介绍了计算机系统的中断处理机制,包括I/O中断、定时器中断和处理器间中断等三种主要类型的中断。文中还深入探讨了中断处理程序的工作流程,以及Linux操作系统如何通过不同的策略分配和管理中断请求。
1572

被折叠的 条评论
为什么被折叠?



