linux中断调用流程(arm)
文章目录
- ARM架构下Linux中断处理全流程解析:从硬件触发到驱动调用 ⚡
- **一、中断触发与硬件层响应** 🔌
- **1. 设备触发中断** 📡
- **二、CPU阶段:异常入口与上下文处理** 🖥️
- **1. 异常模式切换** 🔄
- **2. 跳转至中断向量表** 🗺️
- **三、内核中断处理框架** ⚙️
- **1. 中断向量表初始化** 📜
- **2. 中断控制器驱动注册** 🔧
- **3. 中断分发与设备处理** 🔀
- **四、设备驱动中的中断处理流程** 🛠️
- **1. 驱动注册中断处理函数** 📝
- **2. 实现中断处理函数** 🛠️
- **3. 释放中断资源** 🗑️
- **五、示例:网卡中断处理全流程** 🌐
- **六、关键数据结构与机制** 📊
ARM架构下Linux中断处理全流程解析:从硬件触发到驱动调用 ⚡
一、中断触发与硬件层响应 🔌
1. 设备触发中断 📡
当外设(如网卡、键盘)需要CPU处理时,其硬件控制器会通过物理中断线(IRQ)向中断控制器发送信号。以ARM的通用中断控制器(GICv3)为例:
- 中断接收:GIC Distributor模块接收中断请求,并根据中断类型(SPI/PPI/SGI)分类。
🛠️ 关键点:SPI用于共享外设中断,PPI为CPU私有中断。 - 优先级仲裁:Distributor根据中断优先级(配置于寄存器
GICD_IPRIORITYRn
)和屏蔽状态,选择最高优先级中断。
⚖️ 优先级规则:数值越小优先级越高,0为最高。 - 路由到目标CPU:通过Redistributor模块将中断传递给目标CPU核心(支持多核负载均衡)。
🌐 多核优化:避免单核过载,提升系统吞吐量。 - 物理信号触发:GIC通过CPU的IRQ引脚触发异常模式切换。
⚡ 信号传递:硬件自动完成,无需软件干预。
二、CPU阶段:异常入口与上下文处理 🖥️
1. 异常模式切换 🔄
CPU收到中断信号后,硬件自动完成以下操作:
- 保存上下文:将当前程序状态(
PSTATE
、PC
、SP
等)压入内核栈。
📦 关键寄存器:包括通用寄存器、程序计数器、栈指针。 - 切换异常级别:
- 用户态(EL0)→ 内核态(EL1):触发完整的上下文切换。
🔒 安全隔离:防止用户程序直接访问内核资源。 - 内核态(EL1)→ EL1:仅保存关键寄存器,复用当前内核栈。
⏩ 快速路径:减少模式切换开销。
- 用户态(EL0)→ 内核态(EL1):触发完整的上下文切换。
2. 跳转至中断向量表 🗺️
- 向量表基址:由寄存器
VBAR_EL1
指定,指向内核预定义的向量表(arch/arm64/kernel/entry.S
)。
🏷️ 配置时机:内核启动时通过set_vbar()
初始化。 - 入口偏移计算:
- IRQ入口:
VBAR_EL1 + 0x280
(EL1h模式)。
🔍 偏移规则:每种异常类型有固定偏移量。 - 同步异常入口:
VBAR_EL1 + 0x400
(用于系统调用)。
📌 示例:系统调用通过svc
指令触发同步异常。
- IRQ入口:
// arch/arm64/kernel/entry.S
kernel_ventry 1, irq // EL1h模式IRQ入口
三、内核中断处理框架 ⚙️
1. 中断向量表初始化 📜
ARM64的中断向量表通过汇编宏kernel_ventry
定义,每个条目对应一种异常类型:
- IRQ处理入口:最终调用
handle_arch_irq
(全局函数指针)。
🔗 跳转逻辑:从汇编跳转到C语言函数。 - 关键汇编跳转:
irq_handler:bl handle_arch_irq // 跳转到C语言处理函数
2. 中断控制器驱动注册 🔧
以GIC驱动为例,初始化时完成中断处理函数的绑定:
// drivers/irqchip/irq-gic.c
void __init gic_init(...) {gic_dist_init(gic); // 初始化Distributorgic_cpu_init(gic); // 初始化CPU Interfaceset_handle_irq(gic_handle_irq); // 注册全局处理函数
}
set_handle_irq
:将gic_handle_irq
赋值给handle_arch_irq
,建立汇编到C的桥梁。
🌉 桥梁作用:屏蔽硬件差异,统一中断入口。
3. 中断分发与设备处理 🔀
GIC驱动通过gic_handle_irq
读取中断号并分发给设备驱动:
static void __exception_irq_entry gic_handle_irq(...) {u32 irqnr = gic_read_iar(); // 读取GIC中断应答寄存器handle_domain_irq(gic_data.domain, irqnr, regs); // 映射并处理
}
// kernel/irq/irqdesc.c
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,bool lookup, struct pt_regs *regs) {...irq_enter(); // 进入中断上下文irq = irq_find_mapping(domain, hwirq); // 硬件中断号映射为虚拟中断号if (irq合法) {generic_handle_irq(irq); // 调用中断处理链} else {ack_bad_irq(irq); // 错误处理}irq_exit(); // 退出中断上下文...
}
handle_domain_irq
的核心作用:- 中断上下文标记:
irq_enter()
进入原子上下文,禁用调度。
🚫 禁止行为:禁止睡眠、内存分配等非原子操作。 - 硬件中断号映射:通过
irq_domain
将硬件IRQ转换为Linux虚拟IRQ。
🗂️ 映射策略:支持线性映射、树映射等多种方式。 - 调用设备ISR:从
irq_desc[].action
链表中执行驱动注册的中断处理函数。
⚡ 快速响应:上半部处理时间通常小于1ms。
- 中断上下文标记:
四、设备驱动中的中断处理流程 🛠️
1. 驱动注册中断处理函数 📝
设备驱动通过request_irq
注册中断服务例程(ISR):
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);
- 参数说明:
irq
:虚拟中断号(由irq_of_parse_and_map
解析设备树获得)。
🌳 设备树示例:interrupts = <0 168 IRQ_TYPE_EDGE_RISING>; // SPI 168,上升沿触发
flags
:标志位(如IRQF_SHARED
表示共享中断)。
⚠️ 共享中断:需唯一dev_id
标识不同设备。dev
:设备标识符(共享中断时用于区分设备)。
📌 示例:PCI设备使用pci_dev
指针作为标识。
2. 实现中断处理函数 🛠️
-
上半部(Top Half):快速响应硬件,禁止阻塞或睡眠。
static irqreturn_t my_irq_handler(int irq, void *dev_id) {struct net_device *dev = dev_id;// 1. 读取硬件状态(如网卡DMA缓冲区)u32 status = readl(dev->reg_base + STATUS_REG);// 2. 清除中断标志writel(STATUS_CLEAR, dev->reg_base + STATUS_REG);// 3. 触发下半部(如tasklet)tasklet_schedule(&dev->tasklet);return IRQ_HANDLED; }
🚨 注意事项:避免在中断上下文中调用
kmalloc()
或mutex_lock()
。 -
下半部(Bottom Half):处理耗时任务,支持多种机制:
- SoftIRQ:内核预定义的高优先级任务(如网络收包)。
🌟 优势:支持多CPU并行处理。 - Tasklet:基于SoftIRQ,单CPU串行执行。
⚡ 适用场景:GPIO按键去抖动处理。 - Workqueue:运行于进程上下文,允许休眠。
🛌 示例:文件I/O或网络协议栈处理。
- SoftIRQ:内核预定义的高优先级任务(如网络收包)。
3. 释放中断资源 🗑️
驱动卸载时需调用free_irq
释放中断号:
void free_irq(unsigned int irq, void *dev_id);
⚠️ 内存安全:必须在驱动卸载路径中调用,防止资源泄漏。
五、示例:网卡中断处理全流程 🌐
- 硬件触发:网卡接收数据包,向GIC发送IRQ信号。
📡 触发时机:DMA传输完成或FIFO缓冲区非空。 - GIC路由:Distributor将中断路由至CPU0,分配硬件中断号168。
🔄 负载均衡:GICv3支持动态调整目标CPU。 - CPU跳转:CPU0执行向量表
VBAR_EL1 + 0x280
处的irq
入口。
⏱️ 低延迟:硬件自动跳转,无需软件轮询。 - GIC处理:
gic_handle_irq
读取中断号168,调用handle_domain_irq
。
🔍 中断号解析:通过GICC_IAR
寄存器获取。 - 中断映射:通过
irq_domain
将168映射为Linux虚拟IRQ 200。
🌉 映射关系:存储在irq_desc[200].irq_data.hwirq
。 - 驱动处理:执行
irq_desc[200].action
中的网卡ISR(如NAPI收包)。
🚀 性能优化:NAPI在收包时切换为轮询模式,减少中断风暴。 - 中断返回:恢复上下文,触发软中断(如
NET_RX_SOFTIRQ
)处理数据。
📦 数据传递:sk_buff
从内核空间传递到用户空间。
六、关键数据结构与机制 📊
组件/机制 | 功能说明 | 示例/API |
---|---|---|
GIC Distributor | 接收外设中断,优先级仲裁,路由到目标CPU核心。 | gic_dist_init() |
VBAR_EL1 | 存储中断向量表基址,决定异常入口跳转位置。 | set_vbar() |
irq_domain | 管理硬件中断号(HW IRQ)到Linux虚拟中断号(VIRQ)的映射。 | irq_domain_add_linear() |
irq_desc[] | 全局中断描述符数组,存储中断处理函数链(action 链表)。 | struct irq_desc |
request_irq() | 驱动注册中断处理函数,关联到irq_desc[VIRQ].action 链表。 | request_irq() |
相关文章:

linux中断调用流程(arm)
文章目录 ARM架构下Linux中断处理全流程解析:从硬件触发到驱动调用 ⚡**一、中断触发与硬件层响应** 🔌**1. 设备触发中断** 📡 **二、CPU阶段:异常入口与上下文处理** 🖥️**1. 异常模式切换** 🔄**2. 跳转…...

基于Matlab的多目标粒子群优化
在复杂系统的设计、决策与优化问题中,常常需要同时兼顾多个相互冲突的目标,多目标粒子群优化(MOPSO)算法应运而生,作为群体智能优化算法家族中的重要成员,它为解决此类棘手难题提供了高效且富有创新性的解决…...

【网络安全】——协议逆向与频繁序列提取:从流量中解码未知协议
目录 引言 一、为什么要结合频繁序列提取? 二、四步融合分析法 步骤1:原始流量采集与预处理 步骤2:多粒度序列模式挖掘 层1:单包内字节级频繁项 层2:跨数据包的行为序列 步骤3:关键字段定位与结构假…...

CSS 中等比例缩放的演变:从传统技巧到 aspect-ratio 属性
CSS 中等比例缩放的演变:从传统技巧到 aspect-ratio 属性 在响应式网页设计和多设备兼容成为主流的今天,如何实现元素的等比例缩放成为前端开发中一个重要的课题。无论是图片、视频还是其他容器,都常常需要保持固定的宽高比,以便…...

系统架构设计师—计算机基础篇—进度管理
文章目录 基本概念进程的特征进程的状态前趋图 进程的通信进程的互斥做题方法 进程的同步PV操作做题方法 基本概念 进程的特征 进程通常由程序、数据集合、进程控制块PCB组成。 PCB是一种数据结构,是进程存在的唯一标识。 组织方式说明线性方式把所有PCB组织在一…...

初始提示词(Prompting)
理解LLM架构 在自然语言处理领域,LLM(Large Memory Language Model,大型记忆语言模型)架构代表了最前沿的技术。它结合了存储和检索外部知识的能力以及大规模语言模型的强大实力。 LLM架构由外部记忆模块、注意力机制和语…...

Ollama+AnythingLLM安装
一、文件准备 1. 安装包获取 从联网设备下载: AnythingLLMDesktopInstaller.exe(官网离线安装包) deepseek-r1-1.5b.gguf(1.5B 参数模型文件) 2. 传输介质 使用 U 盘或移动硬盘拷贝以下文件至离线设…...

docker拉取失败
备份原始配置文件 sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak 清理或修复 daemon.json 文件 sudo nano /etc/docker/daemon.json 删除 文件中的所有内容,确保文件为空。 cv下面这个文件内容 { "registry-mirrors": [ &…...

PHP之Cookie和Session
在你有别的编程语言的基础下,你想学习PHP,可能要了解的一些关于cookie和session的信息。 Cookie 参数信息 setcookie(name,value,expire, path, domain); name : Cookie的名称。 value : Cookie的值。 expire : Cookie的过期时间,可以是一…...

【万字长文】基于大模型的数据合成(增强)及标注
写在前面 由于合成数据目前是一个热门的研究方向,越来越多的研究者开始通过大模型合成数据来丰富训练集,为了能够从一个系统的角度去理解这个方向和目前的研究方法便写了这篇播客,希望能对这个领域感兴趣的同学有帮助! 欢迎点赞&…...

CES Asia 2025增设未来办公教育板块,科技变革再掀高潮
作为亚洲消费电子领域一年一度的行业盛会,CES Asia 2025(第七届亚洲消费电子技术贸易展)即将盛大启幕。今年展会规模再度升级,预计将吸引超过500家全球展商参展,专业观众人数有望突破10万。除了聚焦人工智能、物联网、…...

Python详细安装教程——Python及PyCharm超详细安装教程:新手小白也能轻松搞定!(最新版)
Python作为一门简单易学、功能强大的编程语言,近年来在数据分析、人工智能、Web开发等领域广受欢迎。而PyCharm作为一款专业的Python集成开发环境(IDE),提供了强大的代码编辑、调试和项目管理功能,是Python开发者的得力…...

游戏引擎学习第137天
演示资产系统中的一个 bug 我们留下了个问题,你现在可以看到,移动时它没有选择正确的资产。我们知道问题的原因,就在之前我就预见到这个问题会出现。问题是我们的标签系统没有处理周期性边界的匹配问题。当处理像角度这种周期性的标签时&…...

RAGflow升级出错,把服务器灌满了
使用自动化更新命令,从16升级到17,结果发现出现了大问题,不断下载,一直无法下载完毕。 df -h 直接把服务器搞满了。哈哈哈哈~。查看一下: sudo du -sh /var/lib/docker确认是docker里面安装的ragflow有问题。所以&am…...

[数字图像处理]直方图规定化
这里分别使用基于像素手动计算、调用工具箱函数两种方法实现直方图规定化 1.基于像素进行直方图规定化 (1)读取了原始图像和期望图像,并将它们转换为灰度图像 (2)计算原始图像和期望图像的像素概率分布直方图P(i)和…...

OpenMCU(一):STM32F407 FreeRTOS移植
概述 本文主要描述了STM32F407移植FreeRTOS的简要步骤。移植描述过程中,忽略了Keil软件的部分使用技巧。默认读者熟练使用Keil软件。本文的描述是基于OpenMCU_FreeRTOS这个工程,该工程已经下载放好了移植stm32f407 FreeRTOS的所有文件 OpenMCU_FreeRTOS工…...

Redis - 高可用实现方案解析:主从复制与哨兵监控
文章目录 Pre概述Redis 高可用实现方案一、主从复制机制1.1 全量同步流程1.2 增量同步(PSYNC)流程 二、哨兵监控机制2.1 故障转移时序流程 三、方案对比与选型建议四、生产环境实践建议 Pre Redis-入门到精通 Redis进阶系列 Redis进阶 - Redis主从工作…...

SPI硬件设计及通信原理解析
SPI(Serial Peripheral interface,串行外围设备接口),是一种高速的,全双工,同步通信总线。 SPI采用主从控制模式(Master--Slave)架构,一般有1个主设备、一个或多个从设备,使得主设备可以与多个从设备之间实现片间通信。 SPI在芯片管脚中只占用四根线节约了芯片的管脚…...

腾讯云物联网平台(IoT Explorer)设备端使用
1、直接看图流程 2、跑起来demo,修改产品id,设备名称,设备秘钥。 3、连接部分 4、修改默认地址和端口 sdk里面的地址默认是带着产品ID拼接的,咱们现在中铁没有泛域名解析,要改下这里。把+productID都去掉,然后地址里的.也去掉。...

elk的相关的基础
以下是关于ELK(Elasticsearch, Logstash, Kibana)的200个基础问题及其答案,涵盖了ELK的核心概念、组件、配置、使用场景、优化等方面。 Elasticsearch 基础 **什么是Elasticsearch?** 答:Elasticsearch是一个分…...

结合PyMuPDF+pdfplumber,删除PDF指定文本后面的内容
🚀 一、需求场景解析 在日常办公中,我们经常会遇到这样的痛点: 合同处理:收到上百份PDF合同,需要找到"签署页"之后的内容并删除报表加工:批量移除财务报表中的敏感数据区域文档归档:快速提取技术文档的关键章节传统的手动操作方式存在三大致命缺陷: ❗ 耗时…...

张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑
在动力电池行业,BOM(物料清单)成本每降低1%,都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%,单电芯利润率被压缩至3%的生死线。然而,通过张驰咨询的六西格玛方法论ÿ…...

【深度学习CV】【图像分类】从CNN(卷积神经网络)、ResNet迁移学习到GPU高效训练优化【案例代码】详解
摘要 本文分类使用的是resNet34,什么不用yolo v8,yolo v10系列,虽然他们也可以分类,因为yolo系列模型不纯粹,里面包含了目标检测的架构,所以分类使用的是resNet 本文详细介绍了三种不同的方法来训练卷积神经网络进行 CIFAR-10 图…...

《基于HarmonyOS NEXT API 12+,搭建新闻创作智能写作引擎》
在信息爆炸的时代,新闻行业对于内容生产的效率和质量有着极高的要求。AI技术的发展为新闻创作带来了新的变革契机,借助AI智能写作助手,新闻工作者可以快速生成新闻稿件的初稿,大大提高创作效率。本文将基于HarmonyOS NEXT API 12及…...

python代码注释方式
在 Python 中,注释是用于解释代码、提高代码可读性和可维护性的重要工具。Python 支持两种主要的注释方式:单行注释和多行注释。此外,Python 还支持文档字符串(docstrings),用于为模块、函数、类和方法提供…...

小哆啦解题记:螺旋矩阵
小哆啦开始刷力扣的第二十八天 54. 螺旋矩阵 - 力扣(LeetCode) 🌪️ 一场螺旋风暴的较量 在一个阳光明媚的午后,小哆啦悠闲地坐在窗边啃着曲奇,突然,一道神秘的光芒闪过,小智从代码的虚空中出现…...

【C#】委托是什么
在 C# 中,委托(Delegate) 是一种类型安全的函数指针,可以将方法作为参数传递或者保存方法的引用。下面详细介绍一下委托的相关概念和用法: 1. 基本概念 类型安全:委托在声明时会指定方法的返回类型和参数…...

[Lc(2)滑动窗口_1] 长度最小的数组 | 无重复字符的最长子串 | 最大连续1的个数 III | 将 x 减到 0 的最小操作数
目录 1. 长度最小的字数组 题解 代码 ⭕2.无重复字符的最长子串 题解 代码 3.最大连续1的个数 III 题解 代码 4.将 x 减到 0 的最小操作数 题解 代码 1. 长度最小的字数组 题目链接:209.长度最小的字数组 题目分析: 给定一个含有 n 个 正整数 的数组…...

迷你世界脚本玩家接口:Player
玩家接口:Player 彼得兔 更新时间: 2024-07-28 17:49:05 继承自 Actor 具体函数名及描述如下: 序号 函数名 函数描述 1 getAttr(...) 玩家属性获取 2 setAttr(...) 玩家属性设置 3 getHostUin(...) 获取房主uin 4 isMainPlayer(...) …...

三、0-1搭建springboot+vue3前后端分离-springboot整合mybatis plus 之本地安装mysql
一、安装mysql: 官网下载:https://dev.mysql.com/downloads/mysql/?spm5176.28103460.0.0.40f75d27Stx4Xj 网盘分享:http://链接: https://pan.baidu.com/s/1mS_-VxrKAeRL3utBvD64gg?pwd6666 提取码: 6666 复制这段内容后打开百度网盘手机…...