ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux 中断学习(1)

Linux 中断学习(1) 前提基于 linuxarm64gic 框架1. 中断类型基于中断源划分SGI软件写 GICD_SGIR 寄存器0~15多核核间同步 / 唤醒SPI外设中断硬件外设32~1019响应硬件事件PPI私有中断CPU 核心私有外设定时器16~31核心本地硬件事件软中断softirq软件位图标记无 GIC 参与无固定编号内核软件任务延迟处理GIC 手册中对中断类型定义软件可以设置硬件中断的优先级可以设置 写入gic 寄存器里面 如果没有设置gic同时收到俩个中断 gic会先分发哪个中断 目前没有明确定义 各家的芯片处理可能不一样。GIC可能是按照轮询来 比如上次100号中断 这次优先检查101linux 系统的中断号按照GIC规范定义的的irq中断号为基础然后进行映射。linux 管理中断有三个结构体 irq_desc、irq_domain、irq_chipirq_desc中断的 “总控档案”每个软件中断号irqnr对应一个实例管理该中断的处理逻辑、状态、统计是中断管理的 “中枢”。irq_domain中断号的 “翻译官”将不同硬件控制器的 “硬件中断号hwirq” 映射为内核全局唯一的 “软件中断号irqnr”是多控制器中断号的 “统一命名空间”。irq_chip中断控制器的 “硬件驱动”封装具体中断控制器如 GICv2/GICv3、GPIO的底层寄存器操作是内核与硬件控制器的 “硬件无关性接口”2. 中断执行过程硬件触发通过 GPIO 或专用引脚向 GIC 发送中断请求IRQ。GIC 路由GIC 根据中断配置如中断号、优先级将请求路由到指定 CPU 核心的 IRQ 引脚。CPU 异常入口CPU 检测到中断信号触发异常向量表一般是start.S 最前面中的中断入口如el1_irq。arch/arm64/kernel$ vi entry.S汇编代码执行保存 CPU 上下文x0-x31、SP、ELR_EL1、关闭全局中断CPSR.I1、跳转到内核 C 语言处理函数handle_arch_irq。内核核心处理el1h_64_irq_handler–》el1_interrupt (arch/arm64/kernel/entry-common.c)regs 中断寄存器上下文 handler 中断处理函数__el1_irq–》do_interrupt_handler--》 handler(regs); handler其实就是GIC 驱动的gic_handle_irq函数的指针读取 GIC 的 IRQ 号。drivers/irqchip/irq-gic-v3.c/irq-gic.c 中驱动初始的时候设置的handler指向gic_handle_irqgic_handle_irq 处理GICv3和GICv2 处理不一样GICv2 控制器的中断缓存能力比较弱 所以会有一个while 循环查询当前gic 上的中断。如下图的do while循环如果是GICv3 控制器gic_handle_irq--》__gic_handle_irq_from_irqson--》__gic_handle_irqgeneric_handle_domain_irq–》handle_irq_desc这段代码调用就和之前gicv2 中断控制器是一样的通过irq_to_desc(irq)获取对应的irq_desc结构体检查中断状态是否屏蔽、是否在处理中。顶半部执行调用desc-handle_irq如handle_level_irq/handle_edge_irq执行注册的 ISRrequest_irq注册的函数。ISR 仅做紧急操作如读取硬件寄存器数据到缓冲区然后触发底半部如schedule_work。底半部调度软中断 /tasklet 在中断返回时irq_exit执行关中断适合短任务。工作队列由内核线程kworker执行可调度支持睡眠适合长任务。上下文恢复执行irq_return恢复 CPU 上下文开启中断CPSR.I0返回被中断的任务或调度新任务。关键内核函数调/ 中断注册车载驱动中常用 request_irq(irq, isr, IRQF_TRIGGER_RISING, device_name, dev); // 中断核心处理函数 handle_arch_irq() -- gic_handle_irq() -- irq_to_desc() -- desc-handle_irq() // 底半部触发 schedule_work(work); // 工作队列 tasklet_schedule(tasklet); // tasklet raise_softirq(SIRQ_NET_TX); // 软中断
返回列表