Linux的中断处理分析

本文深入探讨了Linux内核中MIPS体系架构下的中断处理机制,从初始化、中断处理函数注册到中断处理过程,详细阐述了中断号、中断处理函数、数据结构和中断处理流程。MIPS将中断视为异常,中断处理分为保护现场、处理中断和恢复现场三个阶段,且介绍了/proc/interrupts文件中的中断信息。
摘要由CSDN通过智能技术生成

        本文以MIPS体系架构为例介绍Linux内核中的中断处理,MIPS架构与其他体系结构的中断处理有很大区别,请注意区分。如果不关注特定体系结构,则1.1和3.1节不必太关注。       

        MIPS中,中断被当作一种异常(第0号异常)来处理。中断由外部设备产生,可能发生在任何时刻,每个中断都有一个编号分配给一个外部设备,这样来区分不同设备产生的中断,如果硬件和内核支持共享中断,则可以由多个设备共享一个中断编号。

        在CPU得知中断发生后,它将进一步的处理委托给一个软件例程,这个软件例程是体系结构相关的,然后根据中断号来识别中断源,并进入特定的中断处理程序来处理该中断。

        中断处理的软件例程大致可分为三部分:

       1.切换到内核态,并保护现场,用于在中断处理后能够执行之前被打断的指令。

       2.根据中断号执行中断处理程序。

       3.恢复现场,内核继续进行后续的常规动作。

1. 初始化

1.1 mips中的中断号

中断初始化主要包括全局数组iqr_desc[]的初始化和中断处理函数的注册。

每个中断信号线都有一个中断描述符iqr_desc,每个iqr_desc包含了中断硬件描述符,中断处理函数链表等。

全局的中断描述符表iqr_desc[NR_IRQS]的定义在kernel/irq/handle.c中。NR_IRQS是允许最多中断号的数量,这个值是平台相关的,例如MIPS某处理器中的取值为128。

struct irq_desc irq_desc[NR_IRQS]__cacheline_aligned_in_smp = {
    [0 ... NR_IRQS-1] = {
       .status= IRQ_DISABLED,
       .chip =&no_irq_chip,
       .handle_irq= handle_bad_irq,
       .depth= 1,
       .lock =__SPIN_LOCK_UNLOCKED(irq_desc->lock),
    }
};

MIPS的协处理器CP0的Cause寄存器中IP0-IP7位分别就对应了其中的0-7号中断,其中0和1用作软件产生的中断,这些中断的中断线可以直接与CPU相连。

但是MIPS允许0-127号中断,那么Cause寄存器中这几个中断号显然不够用,这可以通过硬件中断控制器的级联来达到扩展中断数量的目的,例如,用第6号中断关联一个中断控制器A,该中断控制器分派出22个中断,中断号定义为16~37,之后还可以继续分派更多的中断,只要中断号不超过127。那么,当产生2~5号中断时,CPU可直接判断是何种中断,而当CPU得知第6号中断发生后,通过中断控制器A的内部寄存器可以判断出应该进入哪个中断号对应的处理例程。

1.2 关键数据结构

    iqr_desc[]数组每个元素都是一个struct irq_desc结构:


    关键的两个数据结构为struct irq_desc(中断描述符)和struct irq_chip(特定于具体中断控制器的描述符),定义如下,注释中对各字段的解释也写的很清楚。

/**
 * struct irq_chip - hardware interrupt chip descriptor
 *
 * @name:      namefor /proc/interrupts
 * @startup:      start up the interrupt (defaults to->enable if NULL)
 * @shutdown:     shut down the interrupt (defaults to->disable if NULL)
 * @enable:       enable the interrupt (defaults tochip->unmask if NULL)
 * @disable:      disable the interrupt (defaults tochip->mask if NULL)
 * @ack:      start of a new interrupt
 * @mask:     mask an interrupt source
 * @mask_ack:     ack and mask an interrupt source
 * @unmask:       unmask an interrupt source
 * @eoi:      end of interrupt - chip level
 * @end:       endof interrupt - flow level
 *@set_affinity: set the CPU affinity on SMPmachines
 *@retrigger:       resend an IRQ to the CPU
 * @set_type:     set the flow type (IRQ_TYPE_LEVEL/etc.) ofan IRQ
 * @set_wake:     enable/disable power-management wake-on ofan IRQ
 *
 * @release:      release function solely used by UML
 * @typename
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值