中断-通用架构

中断-通用架构



前言

前面,已经了解了ARM异常和中断控制器,接下来了解中断再linux中的通用架构。


整个软件层次架构

整个架构做简要的介绍:

  1. 系统启动阶段,取决于内核的配置,内核会通过数组或基数树分配好足够多的irq_desc结构;
  2. 根据不同的体系结构,初始化中断相关的硬件,尤其是中断控制器;
  3. 为每个必要irq的irq_desc结构填充默认的字段,例如irq编号,irq_chip指针,根据不同的中断类型配置流控handler;
  4. 设备驱动程序在初始化阶段,利用request_threaded_irq() api申请中断服务,两个重要的参数是handler和thread_fn;
  5. 当设备触发一个中断后,cpu会进入事先设定好的中断入口,它属于底层体系相关的代码,它通过中断控制器获得irq编号,在对irq_data结构中的某些字段进行处理后,会将控制权传递到中断流控层(通过irq_desc->handle_irq);
  6. 中断流控处理代码在作出必要的流控处理后,通过irq_desc->action链表,取出驱动程序申请中断时注册的handler和thread_fn,根据它们的赋值情况,或者只是调用handler回调,或者启动一个线程执行thread_fn,又或者两者都执行;
  7. 至此,中断最终由驱动程序进行了响应和处理。

硬件中断号与软件中断号的映射流程

irq_desc结构的组织方式

基于数组方式

在这里插入图片描述
硬件中断号到Linux irq中断号的映射,并创建好irq_desc中断描述符。irq_domain结构,用于硬件中断号和Linux IRQ中断号(virq,虚拟中断号)之间的映射;

中断注册时,先获取设备的中断号,根据中断号找到对应的irq_desc,并将设备的中断处理函数添加到irq_desc中;

设备触发中断信号时,根据硬件中断号得到Linux irq中断号,找到对应的irq_desc,最终调用到设备的中断处理函数;

基于基数树方式

当内核的配置项CONFIG_SPARSE_IRQ被选中时,内核使用基数树(radix tree)来管理irq_desc结构,这一方式可以动态地分配irq_desc结构,对于那些具备大量IRQ数量或者IRQ编号不连续的系统,使用该方式管理irq_desc对内存的节省有好处,而且对那些自带中断控制器管理设备自身多个中断源的外部设备,它们可以在驱动程序中动态地申请这些中断源所对应的irq_desc结构,而不必在系统的编译阶段保留irq_desc结构所需的内存。

申请IRQ调用关系

在这里插入图片描述
request_irq也是调用request_threaded_irq,只是在传参的时候,线程处理函数thread_fn函数设置成NULL;

由于在硬件中断号和Linux中断号完成映射后,irq_desc已经创建好,可以通过irq_to_desc接口去获取对应的irq_desc;

创建irqaction,并初始化该结构体中的各个字段,其中包括传入的中断处理函数赋值给对应的字段

__setup_irq用于完成中断的相关设置,包括中断线程化的处理:中断线程化用于减少系统关中断的时间,增强系统的实时性;

ARM64默认开启了CONFIG_IRQ_FORCED_THREADING,引导参数传入threadirqs时,则除了IRQF_NO_THREAD外的中断,其他的都将强制线程化处理;

中断线程化会为每个中断都创建一个内核线程,如果中断进行共享,对应irqaction将连接成链表,每个irqaction都有thread_mask位图字段,当所有共享中断都处理完成后才能unmask中断,解除中断屏蔽;

generic_handle_irq

中断收到之后,首先会跳转到异常向量表的入口处,进而逐级进行回调处理,最终调用到generic_handle_irq来进行中断处理。
在这里插入图片描述

  • generic_handle_irq函数最终会调用到desc->handle_irq(),这个也就是对应到上文中在建立映射关系的过程中,调用irq_domain_set_info函数,设置好了函数指针,也就是handle_fasteoi_irq和handle_percpu_devid_irq
  • handle_fasteoi_irq:处理共享中断,并且遍历irqaction链表,逐个调用action->handler()函数,这个函数正是设备驱动程序调用* request_irq/request_threaded_irq接口注册的中断处理函数,此外如果中断线程化处理的话,还会调用__irq_wake_thread()唤醒内核线程;
  • handle_percpu_devid_irq:处理per-CPU中断处理,在这个过程中会分别调用中断控制器的处理函数进行硬件操作,该函数调用action->handler()来进行中断处理;

中断线程化处理后的唤醒流程

在这里插入图片描述

  • __handle_irq_event_percpu->__irq_wake_thread将唤醒irq_thread中断内核线程
  • irq_thread内核线程,将根据是否为强制中断线程化对函数指针handler_fn进行初始化,以便后续进行调用
  • irq_thread内核线程将while(!irq_wait_for_interrupt)循环进行中断的处理,当满足条件时,执行handler_fn,在该函数中最终调用action->thread_fn,也就是完成了中断的处理;
  • irq_wait_for_interrupt函数,将会判断中断线程的唤醒条件,如果满足了,则将当前任务设置成TASK_RUNNING状态,并返回0,这样就能执行中断的处理,否则就调用schedule()进行调度,让出CPU,并将任务设置成TASK_INTERRUPTIBLE可中断睡眠状态;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1.1 特征 .................................................... 1-1 1.2 内部架构概要 ............................................ 1-2 1.3 编程模式 ................................................ 1-3 1.4 数据格式概要 ............................................ 1-4 1.5 操作数寻址方式 .......................................... 1-5 1.6 指令集一览 .............................................. 1-6 2.1 用户编程模式 ............................................. 2-1 2.1.1 通用寄存器 ............................................. 2-1 2.1.2 程序计数器 ............................................. 2-2 2.1.3 条件码/借位 ............................................. 2-2 2.2 管理员编程模式 ........................................... 2-2 2.2.1 替换寄存器组 ........................................... 2-3 2.2.2 处理器状态寄存器 ....................................... 2-4 2.2.2.1 PSR变更 ............................................. 2-6 2.2.2.2 异常识别与处理变更 ................................... 2-6 2.2.2.3 RTE和RFI指令变更 .................................. 2-7 2.2.2.4 MTCR指令变更 ........................................ 2-7 2.2.3 向量基址寄存器 ........................................ 2-7 2.2.4 管理员存储寄存器 ....................................... 2-7 2.2.5 异常影子寄存器 ......................................... 2-7 2.2.6 全局控制寄存器 ......................................... 2-8 2.2.7 全局状态寄存器 ......................................... 2-8 3.1 指令类型和寻址方式 ...................................... 3-1 3.1.1 寄存器--寄存器类指令 .................................. 3-1 3.1.1.1 单寄存器寻址方式 .................................... 3-1 3.1.1.2 双寄存器寻址方式 .................................... 3-1 3.1.1.3 寄存器与5位立即数方式 .............................. 3-2 3.1.1.4 寄存器与5位偏移立即数方式 .......................... 3-2 3.1.1.5 寄存器与7位立即数方式 ............................. 3-2 3.1.1.6 控制寄存器寻址方式 ................................. 3-3 3.1.2 数据存储器访问指令 .................................... 3-3 3.1.2.1 规格化4位立即数寻址方式 ............................ 3-3 3.1.2.2 Load/Store 4个寄存器方式 ........................... 3-3 3.1.2.3 Load/Store 多寄存器方式 ............................. 3-3 3.1.2.4 Load相对字寻址方式 ................................. 3-4 3.1.3 流控制指令 ............................................ 3-4 3.1.3.1 规格化11位位移量方式 .............................. 3-4 3.1.3.2 寄存器寻址方式 ...................................... 3-5 3.1.3.3 间址方式 ............................................ 3-5 3.1.3.4 寄存器与4位负位移寻址方式 .......................... 3-5 3.2 操作码表 ................................................ 3-6 3.3 指令集 .................................................. 3-9 4.1 异常处理一览 ............................................ 4-1 4.2 异常处理步骤 ............................................ 4-2 4.3 异常向量 ................................................ 4-3 4.4 异常类型 ................................................ 4-4 4.4.1 复位异常 (向量位移 0x0) ............................... 4-4 4.4.2 未对界异常(向量位移 0x4) ............................. 4-4 4.4.3 访问异常 (向量位移 0x8) ............................... 4-5 4.4.4 被0除异常 (向量位移 0x0C) ............................ 4-5 4.4.5 非法指令异常 (向量位移 0x10) .......................... 4-5 4.4.6 违反特权异常 (向量位移 0x14) .......................... 4-5 4.4.7 跟踪异常 (向量位移 0x18) .............................. 4-5 4.4.8 断点异常 (向量位移 0x1C) .............................. 4-6 4.4.9 不可恢复错异常 (向量位移 0x20) ........................ 4-7 4.4.10 软件复位异常 (向量位移 0x24) ......................... 4-7 4.4.11 中断异常 ........................................... 4-7 4.4.11.1 正常中断 (INT) ..................................... 4-8 4.4.11.2 快速中断(FINT) ..................................... 4-8 4.4.12 硬件加速器异常 (向量位移 0x30) ....................... 4-8 4.4.13 指令陷阱异常 (向量位移 0x40-0x5C) .................... 4-9 4.5 异常优先级 .............................................. 4-9 4.6 从异常句柄返回 .......................................... 4-11

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦梨甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值