内核中断号必须要跟硬件中断号一致吗

首先说明,答案是否定的,内核中断号可以与硬件中断号不一致,但是这是个无聊的问题。。实用价值不大。但是却可以引起对内核软件中断号与硬件中断号关系的思考。

两者的关系我觉得可以从中断的初始化和分发过程来一探究竟。

这里就从ARM PPC MIPS 3款主流嵌入式处理器架构的内核代码框架中来分析下他们中断的初始化和分发过程。

一 中断的初始化

对于中断初始化,在系统启动过程中,这3款处理器架构的内核软件框架中都会有相应的中断初始化函数.

内核启动函数start_kernel中会调用init_IRQ来进行中断初始化,该函数在不同处理器平台代码有不同实现。实现在arch/xxx/kernel/irq.c中。

对于arm处理器,init_IRQ调用对应设备描述符machine_desc的init_irq。

对于ppc处理器,init_IRQ调用对应设备描述符machdep_calls的init_IRQ。

对于mips处理器,init_IRQ调用arch_init_irq。

最终调用的中断初始化函数是在板级支持包中实现,因为中断控制器属于处理器核的外设。

所以可以看出,中断初始化的调用关系:

通用函数start_kernel -----> 处理器平台级函数init_IRQ -----> 板级中断初始化函数init_irq等

板级中断初始化函数完成2件事情,其一,中断控制器初始化。其二,中断描述符irq_desc的初始化。

中断控制器初始化就不细说了。这里我们主要关心软件上中断描述符的处理。

内核对于中断的管理,最关键的数据结构就是irq_desc,在kernel/irq/irqdesc.c中:

struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
    [0 ... NR_IRQS-1] = {
        .handle_irq = handle_bad_irq,
        .depth      = 1,
        .lock       = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
    }
};

NR_IRQS由不同处理器平台的板级支持包来定义,irq_desc数组成员代表每一个中断号和相应的处理函数。

所以irq_desc[NR_IRQS]就是硬件中断控制器中断号表在内核的表征。

有个前提,这里是在不配置CONFIG_SPARSE_IRQ内核选项的情况下,irq_desc[NR_IRQS]用数组形式静态分配中断描述符表,编译时即确定irq_desc数组大小。

如果配置CONFIG_SPARSE_IRQ则动态分配irq_desc以节省内存。这是另一套机制,这里就不细说了。

板级中断初始化函数中完成其所使用所有中断号对应的irq_desc的初始化,主要是设置中断的一级处理函数。一般是handle_level_irq。函数实现在kernel/irq/chip.c中。

handle_level_irq遍历该irq_desc的action链表,依次执行其action->handler。

各个driver中调用request_irq注册的中断处理函数就是irq_desc各个action的handler成员。这里我们也就明白了内核下共享中断的实现机制了。

内核中断的初始化就是这样。从这里可以看出,irq_desc[NR_IRQS]内核中断号表与硬件中断号表对应。

那么问题来了,我不让他们一一对应,硬件中断号35的处理函数,我想放在irq_desc数组的30号可不可以?

从中断的初始化来看这样的修改是没什么问题,就是数组成员内容换一下。

但是我们要想到中断是来干什么的,中断的初始化以及注册,都是为了能够正确的响应中断进行处理。

所以这个问题的关键在于,这样修改,当产生35号中断时,内核能不能正常找到在30号irq-desc上的处理函数呢。

也就是在中断分发过程中内核如何确定软件中断号,由硬件35号中断找到30号irq_desc。

这个我们就需要来看下内核的中断分发过程了。

二 中断的分发

中断是处理器核异常的一种,所以处理器设计中,外设中断引起处理器异常,处理器跳转到异常向量表的相应异常入口取指执行。

处理器的异常向量表也是软硬件结合很有意思的东西,有时间专门写一篇来记录,这里不详说了。

我们主要来看产生中断后,处理器跳转到中断异常入口后的执行流程。

(1)对于arm处理器,执行流程如下:

vector_irq ---> irq_handler ---> arch_irq_handler_default ---> asm_do_IRQ ---> handle_IRQ

在arch_irq_handler_default中调用get_irqnr_and_base获取中断号,传给asm_do_IRQ作为参数。

get_irqnr_and_base由板级支持包实现。

(2)对于ppc处理器,执行流程如下:

do_IRQ ---> ppc_md.get_irq ---> handle_one_irq

ppc_md.get_irq是由板级支持包中实现的设备描述符的获取中断号函数。

(3)对于mips处理器,执行流程如下:

handle_int ---> plat_irq_dispatch ---> do_IRQ

plat_irq_dispatch由班级支持包中实现。

上述的流程表示由异常入口函数开始,到调用handle_level_irq结束。

对于3款处理器平台,内核在中断分发上没有像中断初始化那样由通用函数到处理器平台函数最后到板级支持函数,而是每种处理器平台都不一样。上述函数的实现都在arch/xxx/kernel下,具体实现可以参考代码。

根据上面的分析可以看出,ARM MIPS PPC在中断分发中中断号的获取都是留给板级支持包来实现的。板级支持包中会读取中断控制器中相关寄存器来获取当前产生的中断情况,进而返回中断号。

所以结合中断初始化部分提出的问题,不管哪款处理器平台,如果我们想将35号中断的中断处理函数在注册时放在30号irq_desc中(方法是request_irq时中断号写30)。

那么在中断分发时,获取中断号函数中我们也需要进行修改,查询到中断控制器寄存器状态是产生35号中断,我们返回的中断号应该是30号!

但是,这样做并没有实际的应用意义,因为在实际开发中还是要尽量保证内核下irq_desc数组与硬件中断号表一一对应,这样驱动开发者在操作中断时就不需要关心内核中断号和硬件中断号的关系,而是直接使用硬件中断号来注册就可以了。

如果内核中断号和硬件中断号不一一对应,驱动开发者在编写驱动时还需要查找硬件中断号和内核中断号的映射表,增大了开发难度。

无论如何,借这个无聊的问题,还是搞清了内核中断的初始化和分发过程,也是很值得的

但求好事,莫问前程!

时间: 2024-07-31 13:28:38

内核中断号必须要跟硬件中断号一致吗的相关文章

内核中断号必需要跟硬件中断号一致吗

首先说明.答案是否定的,内核中断号能够与硬件中断号不一致.可是这是个无聊的问题.. 有用价值不大.可是却能够引起对内核软件中断号与硬件中断号关系的思考. 两者的关系我认为能够从中断的初始化和分发过程来一探到底. 这里就从ARM PPC MIPS 3款主流嵌入式处理器架构的内核代码框架中来分析下他们中断的初始化和分发过程. 一 中断的初始化 对于中断初始化,在系统启动过程中,这3款处理器架构的内核软件框架中都会有对应的中断初始化函数. 内核启动函数start_kernel中会调用init_IRQ来

Linux 多核下绑定硬件中断到不同 CPU

硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能.现在的服务器上动不动就是多 CPU 多核.多网卡.多硬盘,如果能让网卡中断独占1个 CPU (core).磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担.提高整体处理效率.VPSee 前天收到一位网友的邮件提到了 SMP IRQ Affinity,引发了今天的话题:D,以下操作在 SUN FIre X2100 M2

《Linux内核设计与实现》学习笔记——中断、中断处理程序

中断和中断处理程序 中断随时可能产生,打断CPU的执行,CPU转而处理中断. 不同的设备对应的中断不同,每个中断都通过一个唯一的数字标志. 这些中断值称为中断请求(IRQ)线,每个irq线关联一个数值. 中断处理程序 响应中断时,内核会执行一个函数,中断处理程序/中断服务例程ISR, 一个设备的中断处理程序是他的设备驱动的一部分. IO资源包括 : 中断,I/O端口,共享RAM,DMA.驱动程序需要管理注册释放这些资源. 上半部:接收到中断就立即执行,只做有严格时限的工作,如对中断应答或复位硬件

把握linux内核设计(二):硬中断及中断处理

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 操作系统负责管理硬件设备,为了使系统和硬件设备的协同工作不降低机器性能,系统和硬件的通信使用中断的机制,也就是让硬件在需要的时候向内核发出信号,这样使得内核不用去轮询设备而导致做很多无用功. 中断使得硬件可以发出通知给处理器,硬件设备生成中断的时候并不考虑与处理器的时钟同步,中断可以随时产生.也就是说,内核随时可能因为新到来的中断而被打断.当接收到一个中断后,中断控制器会给处

Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity) 转

硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同的 CPU (core) 处理显然能很好的平衡性能.现在的服务器上动不动就是多 CPU 多核.多网卡.多硬盘,如果能让网卡中断独占1个 CPU (core).磁盘 IO 中断独占1个 CPU 的话将会大大减轻单一 CPU 的负担.提高整体处理效率.VPSee 前天收到一位网友的邮件提到了 SMP IRQ Affinity,引发了今天的话题:D,以下操作在 SUN FIre X2100 M2

硬件中断和软件中断以及中断与函数调用的区别

<汇编语言程序设计>Richard Blum著:6.2.3中断   中断有两种形式: (1)硬件中断: (2)软件中断.   硬件设备生成硬件中断. 使用硬件中断发出信号,表示硬件层发生的事件(比如I/O端口接收到输入信号时).   程序生成软件中断. 它们是把控制交给另一个程序的信号.   当一个程序被中断调用时,发出调用的程序暂停,被调用的程序接替它运行.指令指针被转移到被调用的程序,并且从被调用的程序内继续执行.被调用的程序完成时,它可以把控制返回给发出调用的程序(使用中断返回指令).

中断与中断向量、硬件中断与软件中断、可屏蔽中断与不可屏蔽中断(转)

转载url:http://blog.sina.com.cn/s/blog_553fab3b0100y1sa.html ■看图理解:硬件中断与软件中断(内部中断与外部中断) 1.8086/8088CPU可以处理256种不同类型的中断,每一种中断都给定一个编号(0~255),称为中断类型号,CPU根据中断类型号来识别不同的中断源: 2.中断类型号0~4已有固定对应对象(例如0=除法错误等),中断类型号5~31保留给BIOS: 3.可屏蔽中断请求信号从INTR引脚送往CPU,高电平有效,受IF标志位屏

内核怎么通过主设备号找驱动、次设备号找设备

之前看韦东山老师视频,说到linux驱动就知道主设备号找驱动,次设备号找设备.这句到底怎么理解呢,如何在驱动中实现呢,在介绍该实现之前先看下内核中主次设备号的管理.在内核中,dev_t  类型( 在 <linux/types.h>头文件有定义 ) 用来表示设备号,包括主设备号和次设备号两部分.对于 2.6.x内核,dev_t是个32位量,其中高12位用来表示主设备号,低20位用来表示次设备号. <span style="font-family:Times New Roman;f

什么是中断,什么是俘获,中断和俘获有什么不同?

中断: 由处理机外部事件引起的中断称为外中断,又称中断.在x86中称之为异步中断,它是随着CPU的时钟随机产生的,又能发生在一条指令执行过程中,也可能发生在一条指令执行之后.包括I/O中断.外中断. 俘获: 由处理机内部事件引起的中断称之为俘获,在x86中称为异常,也称同步中断,包括访管中断.程序性中断.机器故障中断.同步中断值得是由CPU控制单元产生,是在一条指令执行之后才会发出的中断. 不同点: 中断是由处理机外部事件引起的,俘获是由内部事件引起的. 在同时发生中断和俘获请求时,俘获总是优先