Linux中断的响应流程

本文深入探讨了Linux内核在CPU检测到中断时的处理流程,从arch/arm/kernel/entry-armv.S开始,通过vector_irq、handle_arch_irq到gic_handle_irq,再到中断处理的细节,包括中断号映射、硬件中断号到软件中断号的转换、desc->handle_irq的初始化及实际的中断处理函数handle_fasteoi_irq。通过对desc->handle_irq的分析,揭示了中断处理的完整路径。
摘要由CSDN通过智能技术生成

原创文章, 转载请注明出处。

这篇文章主要讨论的话题是当中断发生时Linux内核是如何处理中断的。

当CPU检测到中断的时候,linux内核首先会跳转至arch/arm/kernel/entry-armv.S中进行处理,
然后切换到IRQ_MODE(vector_stub   irq, IRQ_MODE, 4),最后运行到irq_handler。code如下:

vector_irq: irq中断的入口, vector_irq的定义为:vector_stub
vector_stub     irq, IRQ_MODE, 4

__irq_svc:
        svc_entry
        irq_handler

.macro  irq_handler
        ldr     r1, =handle_arch_irq
        mov     r0, sp
        ldr     pc, [r1]


可知该段汇编最终会调用handle_arch_irq,那么handle_arch_irq是什么呢?想了解这个问题,
需要对gic的初始化过程进行分析, code如下:
gic_of_init() drivers/irqchip/irq-gic.c
->__gic_init_bases()
->set_handle_irq(gic_handle_irq)
{
handle_arch_irq = handle_irq;
}


至此,中断处理过程从汇编跳到了C语言,不熟悉汇编的人可以放松下来了,继续分析:
gic_handle_irq(struct pt_regs *regs) drivers/irqchip/irq-gic.c 
{
1. 获取struct gic_chip_data的结构体gic,gic = &gic_data[0];

2. 获取cpu interface的base address,void __iomem *cpu_base = gic_data_cpu_base(gic);

3. do while(1)循环进行中断处理
{
1. 获得硬件中断号
{
1. irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
2. irqnr = irqstat & GICC_IAR_INT_ID_MASK;
}

2. if (likely(irqnr > 15 && irqnr < 1020)), 如果为PPI或SPI中断, 走irq domain的处理方式 
{
irq_enter()
{
account_irq_enter_time(current); 
                                preempt_count_add(HARDIRQ_OFFSET);
}

__handle_domain_irq(gic->domain, irqnr, regs);
{
1. 保护现场, struct pt_regs *old_regs = set_irq_regs(regs);

2. 根据硬件中断号找到gic domain对应的软件中断号, 如果找到的软件中断号有误,直接返回
{
irq = irq_find_mapping(dom

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值