内核深度解析--中断
<div class='showpostmsg'><p> 软件通过中断号识别中断,每个中断号唯一对应一个中断源。 中断有以下4种类型。 <br /> (1)软件生成的中断(Software Generated Interrupt,SGI):中断号0~15,通常用来实现处理器间中断(Inter-Procesor Interrupt,IPI)。这种中断是由软件写分发器的软件生成中断寄存器(GICD_SGIR)生成的。 <br />
(2)私有外设中断(Private Peripheral Interrupt,PPI):中断号16~31。处理器私有的中断源,不同处理器的相同中断源没有关系,比如每个处理器的定时器。 <br />
(3)共享外设中断(Shared Peripheral Interrupt,SPI):中断号32~1020。这种中断可以被中断控制器转发到多个处理器。 <br />
(4)局部特定外设中断(Locality-specific Peripheral Interrupt,LPI):基于消息的中断。 GIC vI和GIC v2不支持LPI。 <br />
中断可以是边沿触发(edge-triggered),也可以是电平触发(level-triggered)。边沿触发是在电压变化的一瞬间触发,电压由高到低变化触发的中断称为下降沿触发,电压由低到高变化触发的中断称为上升沿触发。电平触发是在高电压或低电压保持的时间内触发, 低电压触发的中断称为低电平触发,高电压触发的中断称为高电平触发。 </p>
<p><br />
中断有以下4种状态。 <br />
(1)Inactive:中断源没有发送中断。</p>
<p> (2)Pending:中断源已经发送中断,等待处理器处理。</p>
<p> (3)Active:处理器已经确认中断,正在处理。 <br />
(4)Active and pending:处理器正在处理中断,相同的中断源又发送了一个中断。<br />
中断的状态转换过程如下。 <br />
(1)Inactive->Pending:外围设备发送了中断。</p>
<p> (2)Pending->Active:处理器确认了中断。</p>
<p> (3)Active->Inactive:处理器处理完中断。 </p>
<p> </p>
<p> 对于中断控制器的每个中断源,向中断域添加硬件中断号到Linux中断号的映射时, 内核分配一个Linux中断号和一个中断描述符irg_desc,中断描述符有两个层次的中断处理函数。 <br />
(1)第一层处理函数是中断描述符的成员handle_irq()。 <br />
(2)第二层处理函数是设备驱动程序注册的处理函数。中断描述符有一个中断处理链表(irq_desc.action),每个中断处理描述符(irq_action)保存设备驱动程序注册的处理函数。因为多个设备可以共享同一个硬件中断号,所以中断处理链表可能挂载多个中断处理描述符。</p>
<p> 怎么存储Linux中断号到中断描述符的映射关系?有两种实现方式。 <br />
(1)如果中断编号是稀疏的(即不连续),那么使用基数树(radix tree)存储。需要开启配置宏CONFIG SPARSE IRQ。 <br />
(2)如果中断编号是连续的,那么使用数组存储。 </p>
<pre>
<code>kernel/irq/irqdesc.C
#ifdef CONFIG_SPARSE_IRQ
static RADIX_TREE(irg_desc_tree, GFP_KERNEL);
#else
struct irq_desc irq_desc __cacheline_aligned_in_smp = {
= {
.handle_irq= handle bad irq,
.depth = 1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
}
};
#endif </code></pre>
<p> ARM64架构默认开启配置宏CONFIG_SPARSE_iRQ,使用基数树存储。</p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> <p>很基础底层的知识,以前了解了一部分,现在再看到这方面的资料,很亲切,很好的资料</p>
页:
[1]