Linux 系统中断是如何处理的?
发布时间 - 2026-01-30 00:00:00 点击率:次CPU在当前指令执行完后立即暂停任务,硬件自动压入PC、CPSR/RIP/RFLAGS等寄存器到栈;随后经硬件向量跳转、中断控制器仲裁、内核asm_do_IRQ()三层调度才进入handler。
中断触发后,CPU 怎么第一时间“停下手头活”?
硬件中断信号(比如网卡收到包、键盘按键)到达 CPU 的 INTR 引脚后,CPU 在当前指令执行完的边界立即暂停用户态或内核态任务,自动压入 PC、CPSR(ARM)或 RIP/RFLAGS(x86_64)等关键寄存器到当前栈——这一步完全由硬件完成,不依赖内核代码。你写驱动时看不到它,但它是整个中断流程不可绕过的起点。
常见误区是以为“中断一来就跳进你的 irq_handler_t”,其实中间隔着至少三层:硬件向量跳转 → 中断控制器(如 GIC 或 APIC)仲裁 → 内核通用入口 asm_do_IRQ()。如果你在 /proc/interrupts 里看到某 IRQ 计数不动,大概率是硬件没发信号,或者中断控制器配置漏了使能位(比如 GICD_CTLR 寄存器没置位)。
request_irq() 注册的是顶半部,但它到底干了什么?
调用 request_irq() 不是把函数直接塞进硬件,而是把你的处理函数挂到对应 irq_desc[irq] 结构体的 action 链表上,并让内核在该 IRQ 触发时调用 handle_irq() —— 这个函

action 链表,逐个执行注册的 handler。所以多个驱动可以共享一个 IRQ(如 PCI 设备),只要每个 handler 开头都检查自己设备的中断状态寄存器是否真被触发。
- 必须用
IRQF_SHARED标志才能和别人共用 IRQ,否则request_irq()直接失败 - handler 函数运行在中断上下文,不能调用
sleep()、copy_to_user()、mutex_lock()等可能阻塞的函数 - 返回值只能是
IRQ_NONE(不是我的中断)、IRQ_HANDLED(我处理了)、IRQ_WAKE_THREAD(交给线程化底半部)
为什么 ISR 里不能做耗时操作?底半部怎么选?
顶半部执行时,同 IRQ 会被自动屏蔽(disable_irq_nosync() 效果),如果在里面解析完整 TCP 包、写磁盘、分配大内存,其他设备(比如鼠标、定时器)就会卡住——你拖动窗口延迟、音频断续,根源可能就在这几行代码里。
Linux 提供三类底半部机制,选错会影响实时性或吞吐:
-
softirq:内核编译时静态分配,高优先级、无锁、可重入,适合网络协议栈(NET_TX_SOFTIRQ)等极致性能场景,但必须用open_softirq()预注册,驱动一般不用 -
tasklet:基于 softirq 封装,单 CPU 串行执行,简单安全,适合大多数驱动(如 USB 主机控制器),但已标记为 legacy,新驱动建议避开 - 线程化中断(
IRQF_ONESHOT | IRQF_TRIGGER_*+request_threaded_irq()):把耗时部分放进内核线程,可调度、可睡眠、可使用全部内核 API,现代驱动首选
/proc/interrupts 和 cat /sys/firmware/devicetree/base/interrupt-controller@.../interrupts 对不上怎么办?
这是嵌入式开发最常踩的坑:设备树里写的 interrupts = ,对应的是 GIC SPI 中断号 23,但 /proc/interrupts 显示的是 Linux 全局 IRQ 编号(通常是 GIC 基地址 + 23)。如果你用 request_irq(23, ...) 肯定失败——得查 gic_irq_domain_translate() 或直接看启动日志里 “GICv2: using LPIs, GICD_BASE=0x...” 后推算,或者更稳妥:用 platform_get_irq() 从设备结构体里取,它已帮你做了映射。
另一个隐藏陷阱:某些 SoC(如 i.MX6ULL)的 GPIO 中断需要先调用 gpio_to_irq() 转换,而这个转换依赖 pin controller driver 是否已 probe 完成——如果驱动 initcall 顺序不对,gpio_to_irq() 可能返回 -EINVAL。
# linux
# usb
# 栈
# ai
# 无锁
# 为什么
# red
# 封装
# 结构体
# using
# 线程
# 的是
# 半部
# 跳转
# 这是
# 链表
# 就会
# 鼠标
# 多个
# 你在
# 遍历
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
如何实现javascript表单验证_正则表达式有哪些实用技巧
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
JavaScript如何实现倒计时_时间函数如何精确控制
Laravel如何实现事件和监听器?(Event & Listener实战)
微信小程序 canvas开发实例及注意事项
如何在万网主机上快速搭建网站?
黑客如何通过漏洞一步步攻陷网站服务器?
Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程
如何基于PHP生成高效IDC网络公司建站源码?
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
如何在不使用负向后查找的情况下匹配特定条件前的换行符
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
深圳网站制作平台,深圳市做网站好的公司有哪些?
如何在云虚拟主机上快速搭建个人网站?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
奇安信“盘古石”团队突破 iOS 26.1 提权
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
高端建站三要素:定制模板、企业官网与响应式设计优化
如何选择可靠的免备案建站服务器?
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
如何用AI帮你把自己的生活经历写成一个有趣的故事?
JavaScript Ajax实现异步通信
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
微信小程序 五星评分(包括半颗星评分)实例代码
简单实现jsp分页
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
如何在新浪SAE免费搭建个人博客?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
如何在腾讯云免费申请建站?
北京的网站制作公司有哪些,哪个视频网站最好?
详解jQuery停止动画——stop()方法的使用
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
Laravel如何使用Blade模板引擎?(完整语法和示例)
昵图网官方站入口 昵图网素材图库官网入口
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
如何挑选最适合建站的高性能VPS主机?
linux top下的 minerd 木马清除方法
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】

