ARM64平台如何实现类x86_64的软件触发中断?
ARM64 中断机制概述
ARM64架构依赖**GIC(通用中断控制器)**管理中断,与x86_64的中断模型差异显著:
- 中断分为三类:SGI(软件生成中断,ID 0-15,用于核间通信或软件触发)、PPI(私有外设中断,ID 16-31)、SPI(共享外设中断,ID 32+)
- 无x86独有的
vector_irqper-cpu变量,中断映射与触发逻辑由GIC硬件及内核封装接口实现 - 软件触发中断通常使用SGI,或通过直接操作GIC寄存器触发SPI中断
适配ARM64的软件触发中断实现方案
针对你的Ubuntu Server 22.04 ARM64(内核5.15.0-71)环境,按以下步骤修改驱动:
1. 移除x86平台专属代码
直接删除所有涉及vector_irq的代码,该符号为x86架构私有,ARM64内核无此定义。
2. 替换中断触发逻辑
方案一:使用SGI(软件生成中断)
SGI是ARM64原生支持的软件触发中断,适合核间通信或本地软件触发场景,使用内核封装的gic_send_sgi接口:
#include <linux/irqchip/arm-gic.h> #include <linux/smp.h> static ssize_t etx_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { int ret; const unsigned int sgi_id = 0; // 可选SGI ID范围0-15,避免占用内核默认使用的ID cpumask_t target_cpus; // 指定触发目标CPU(示例为当前CPU) cpumask_clear(&target_cpus); cpumask_set_cpu(smp_processor_id(), &target_cpus); // 触发SGI中断 ret = gic_send_sgi(sgi_id, &target_cpus); if (ret) { pr_err("SGI trigger failed: %d\n", ret); return ret; } pr_info("SGI interrupt triggered\n"); return len; }
方案二:使用SPI中断(自定义外设中断)
若需要模拟外设中断的触发逻辑,可申请一个未被占用的SPI中断,通过GIC寄存器触发:
#include <linux/irq.h> #include <linux/irqchip/arm-gic.h> #include <linux/smp.h> static int irq_num; // 需替换为系统可用的SPI中断号,可通过`cat /proc/interrupts`查看 // 中断处理函数 static irqreturn_t etx_irq_handler(int irq, void *dev_id) { pr_info("Interrupt received\n"); return IRQ_HANDLED; } // 模块初始化时申请中断 static int __init etx_driver_init(void) { int ret; // 替换为实际可用的SPI中断号 irq_num = 50; ret = request_irq(irq_num, etx_irq_handler, IRQF_SHARED, "etx_softirq", NULL); if (ret) { pr_err("Request irq failed: %d\n", ret); return ret; } pr_info("Driver loaded\n"); return 0; } // 在read函数中触发SPI中断 static ssize_t etx_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { struct irq_desc *desc = irq_to_desc(irq_num); if (!desc) { pr_err("Invalid irq number\n"); return -EINVAL; } // 通过GIC寄存器触发中断 gic_raise_softirq(cpumask_of(smp_processor_id()), irq_num); pr_info("SPI interrupt triggered\n"); return len; }
3. 内核配置与验证
- 确保内核已开启
CONFIG_GIC(ARM64 Ubuntu默认开启) - 加载驱动后,可通过
dmesg查看中断触发与处理日志 - 若SGI触发失败,需确认所选SGI ID未被内核占用(可参考内核文档中SGI的分配规则)
内容的提问来源于stack exchange,提问作者Dooraim
相关产品推荐
相关产品推荐

