栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux 中断子系统(一)-中断控制器和驱动源码分析

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux 中断子系统(一)-中断控制器和驱动源码分析

1、中断概念


        中断是处理器用于异步处理外围设备请求的一种机制,是操作系统中外围设备的基石,此外系统调度、核间交互等都是离不开中断的。
        其概要分布图主要如下:



硬件层:对应具体的外设与soc的物理连接,中断信号是从外设到中断控制器,由中断控制器统一管理,再路由到处理器上;
硬件相关层:这一层包含两个部分,一部分是架构相关的中断处理,另一部分是中断控制器相关的处理;
通用层:属于硬件无关层,其逻辑在所有硬件平台上通用
用户层:主要是各类设备驱动,通过中断相关接口来进行申请和注册,最终在外设触发中断时,进行相应的回调处理。

 
2、GIC(Generic Interrupt Controller,中断控制器)原理

        ARM公司提供了一个通用的中断控制器GIC(Generic Interrupt Controller),GIC的版本包括V1 - V4,本节来看看V2

  • GIC-V2从功能上说,除了常用的中断使能、中断屏蔽、优先级管理等功能外,还支持安全扩展、虚拟化等;
  • GIC-V2从组成上说,主要分为Distributor和CPU Interface两个模块,Distributor主要负责中断源的管理,包括优先级的处理,屏蔽、抢占等,并将最高优先级的中断分发给CPU Interface,CPU Interface主要用于连接处理器,与处理器进行交互;

  来一张细节图看看Distributor和CPU Interface的功能:



Distributor 功能:

        (1)全局开关控制 Distributor 分发到CPU Interface;
        (2)打开或关闭每个中断;

        (3)设置每个中断的优先级;

        (4)设置每个中断将路由的CPU列表;

        (5)设置每个外设中断的触发方式:电平触发、边缘触发;
        (6)设置每个中断的Group:Group0或Group1,其中Group0用于安全中断,
        (7)支持FIQ和IRQ,Group1用于非安全中断,只支持IRQ;

        (8)将SGI中断分发到目标CPU上;

        (9)每个中断的状态可见;

        (10)提供软件机制来设置和清除外设中断的pending 状态;


CPU Interface 功能:

        (1)使能中断请求信号到CPU上;

        (2)中断的确认;
        (3)标识中断处理的完成;

        (4)为处理器设置中断优先级掩码;

        (5)设置处理器的中断抢占策略;

        (6)确定处理器的最高优先级pending 中断;


GIC检测中断流程如下:
(1)GIC捕获中断信号,中断信号 assert,标记为pending 状态;
(2)Distributor 确定好目标CPU后,将中断信号发送到目标CPU上,同时,对
于每个CPU,Distributor 会从 pending 信号中选择最高优先级中断发送至CPU
Interface;
(3)CPU Interface来决定是否将中断信号发送至目标CPU;
(4)CPU完成中断处理后,发送一个完成信号EOI(End of Interrupt)给GIC;


3、GIC驱动分析 3.1 设备信息添加

         ARM平台上的设备信息都是通过Device Tree 设备树来添加的,设备树信息放置在arch/arm64/boot/dts/或 arch/arm/boot/dts/目录下;Device Tree 最终会编译成dtb文件,并通过Uboot 传递给内核,在内核启动后会将dtb文件解析成device_node结构。

下图就是一个中断控制器的设备树信息:

 (1) compatible 字段:用于与具体的驱动来进行匹配,比如图片中 arm,gic-400,可以根据这个名字去匹配对应的驱动程序;


(2)interrupt-cells 字段:用于指定编码一个中断源所需要的单元个数,这个值为3。比如在外设在设备树中添加中断信号时,通常能看到类似interrupts=<0 23 4>;的信息,第一个单元0,表示的是中断类型(1:PPI,0:SPI),第二个单元23表示的是中断号,第三个单元4表示的是中断触发的类型;


(3)reg 字段:描述中断控制器的地址信息以及地址范围,比如图片中分别制定了GIC Distributor(GICD)和GIC CPU Interface(GICC)的地址信息;


(4) interrupt-controller 字段:表示该设备是一个中断控制器,外设可以连接在该中断控制器上;


设备树的添加路径如下所示:
        设备树的信息,是怎么添加到系统中的呢?Device Tzee 最终会编译成 dtb文件,并通过Uboot传递给内核,在内核启动后会将文件解析成 device_nede 结构:


       a) 设备树的节点信息,最终会变成 device_node 结构,在内存中维持一个树状结构;
       b) 设备与驱动,会根据 cospacibie字段进行匹配;


3.2 GIC的驱动源码分析-初始化部分

代码路径:arch\arm64\kernel\Irq.c
(1) 初始化模块

asmlinkage_visible void_init start_kernel(void)====→init_IRQ(void)



init_IRQ(void)-----→ init_irq_stacks()
                                    
    ------→irqchip_init()                  
    ------→of_irq_init(__irqchip_of_table)
    ------→acpi_probe_device_table(irqchip)



(2) of_irq_init(_irqchip_of_table)

of_irq_init(_irqchip_of_table)
/*** drivers\of\Irq.c ----浏览设备树来匹配中断控制器,并按照父节点顺序来调用初始化函数 ***/

  -----→desc->irq_init_cb=match->data         /*** 解析节点,获取回调函数 ***/

  -----→desc->dev=of_node_get(np);

  -----→desc->interrupt_parent=of_irq_find_parent(np);

  -----→desc->irq_init_cb(desc->dev,desc->interrupt_parent);

        -----→gic_of_init                     /*** driversirqchipIrq-gic.c ***/


(3) gic_of_init()

gic_of_init()

    ---→gic_of_setup(gic,node)                     // 设置GIC的地址和寄存器

    ---→_gic_init_bases(gic,&node->fwnode)  // 设置GIC相关基础信息

        ---→set_smp_cross_call(gic_raise_softirq)
            

        ---→cpuhp_setup_state_nocalls(,gic_starting_cpu,);
            

        ---→set_handle_irq(gic_handle_irq);
            

        ---→gic_init_chip(gic,NULL,name,true);
            

        ---→gic_init_bases(gic, handle);
            


(4)gic_init_bases(gic,handle)

gic_init_bases(gic,handle)

    ----→irq_domain_create_linear(,,&gic_irq_domain_hierarchy_ops,);
            

    ----→gic_dist_init
            

    ----→gic_cpu_init
        

    ----→gic_pm_init
        


(5)大概流程


        1)首先需要了解一下链接脚本vmlinux.lds,脚本中定义了一个_irqchip_of_table段,该段用于存放中断控制器信息,用于最终来匹配设备;
        2)在GIC 驱动程序中,使用 IRQCHIP_DECLARE 宏来声明结构信息,包括compatible字段和回调函数,该宏会将这个结构放置到_irqchip_of_table字段中;
        3)在内核启动初始化中断的函数中,of_irq_init函数会去查找设备节点信息,该函数的传入参数就是_irqchip_of_table段,由于IRQCHIP_DECLARE已经将信息填充好了,of_irq_init函数会根据arm,gic-400去查找对应的设备节点,并获取设备的信息。中断控制器也存在级联的情况,of_irq_init函数中也处理了这种情况;
        4)or_irq_init函数中,最终会回调IRQCHIP_DECLARE声明的回调函数,也就是gic_of_init,而这个函数就是GIC驱动的初始化入口函数了;


(6)常用数据结构


        struct gic_chip_data:描述GIC控制器的信息,整个驱动都是围绕着该结构体的初始化,驱动中将函数指针都初始化好,实际的工作是由中断信号触发,也就是在中断来临的时候去进行调;
        struct irq_chip:描述的是中断控制器的底层操作函数集,这些函数集最终完成对控制器硬件的操作;
        struct irq_domain:用于硬件中断号和Linux IRQ 中断号(virq,虚拟中断号)之间的映射;


IRQ Domain 支持三种映射方式:linear map(线性映射),tree map(树映射),no map(不映射);
        linear map:维护固定大小的表,索引是硬件中断号,如果硬件中断最大数量固定,并且数值不大,可以选择线性映射;
        tree map:硬件中断号可能很大,可以选择树映射;
        no map:硬件中断号直接就是Linux的中断号;


4、ARM64 中断异常逻辑


(1)Gic of init()

Gic of init()
    ---→_gic_init_bases()            

    ---→set_handle_irq(gic_handle_irq)

        ---→readl_relaxed(cpu_base+GIC_CPU_INTACK)

        ---→irqstat&GICC_IAR_INT_ID_MASK
                

        ---→irqnr>15&&irqnr<1020
            ---→handle_domain_irq(gic->domain,irqnr,regs)

        ---→irqnr<16
            ---→handle_IPI(irqnr,regs)
                


(2)handle_domain_irq(gic->domain,irqnr,regs)
 

handle_domain_irq(gic->domain,irqnr,regs)             

    ---→_handle_domain_irq(domain,hwirq,true,regs)    

        ---→irq_find_mapping(domain,hwirq)            

        ---→generic_handle_irq(irq)

            ---→generic_handle_irq_desc(desc)         
                                    

        ---→irq_exit()                                


        1)中断触发,处理器去异常向量表找到对应的入口,比如EL0的中断跳转到el0_irq处,EL1则跳转到el1_irq处;
        2)在GIC驱动中,会调用set_handle_irq 接口来设置 handle_arch_irq的函数指针,让它指向 gic_handle_irq,因此中断触发的时候会跳转到gic_handle_irq 处执行;

参考链接:
Linux中断子系统(二)中断控制器GIC驱动分析_枫潇潇-CSDN博客_smp_cross_call

【原创】Linux中断子系统(一)-中断控制器及驱动分析 - LoyenWang - 博客园

设备树学习(十八、番外篇-中断子系统之初始化一个中断控制器)_To_run_away的博客-CSDN博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/680594.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号