Understanding the linux kernel-ch4-Interrupt Handling

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)      
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值