您的位置:首页 > 运维架构 > Linux

Understanding the linux kernel-ch4-Interrupt Handling

2008-07-03 20:27 471 查看
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_INPROGRESS1/* IRQ handler active - do not enter! */
#define IRQ_DISABLED2/* IRQ disabled - do not enter! */
#define IRQ_PENDING4/* IRQ pending - replay on enable */
#define IRQ_REPLAY8/* IRQ has been replayed but not acked yet */
#define IRQ_AUTODETECT16/* IRQ is being autodetected */
#define IRQ_WAITING32/* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL64/* IRQ level triggered */
#define IRQ_MASKED128/* IRQ masked - shouldn't be seen again */
#define IRQ_PER_CPU256/* IRQ is per CPU */
void disable_irq(unsigned int irq)
void enable_irq(unsigned int irq)
void __init init_IRQ(void)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: