281|3

7228

帖子

195

TA的资源

五彩晶圆(高级)

楼主
 

《Linux内核深度解析》第4章 异常与中断学习 [复制链接]

在ARM64和MIPS这些精简指令集计算机(RISC)体系结构中,中断系统调用和其他打断程序正常执行流的事件统称为异常,这是广义的异常。

异常级别,4个异常级别0-3

 

 

异常分为同步异常和异步异常

同步异常是试图执行指令时产生的异常,或是作为指令的执行结果生成的异常。

同步异常包括:

(1)系统调用,例如异常级别0使用SVC指令陷入异常级别1

(2)数据中止,即访问数据时的页错误异常,虚拟地址没有映射到物理地址,或者没有写权限

(3)指令中止,即取指令时的页错误异常,虚拟地址没有映射到物理地址,或没有执行权限

(4)栈指针或指令地址没有对齐

(5)没有定义的指令

(6)调试异常

 

异步异常,不是由正在执行的指令生成的,和正在执行的指令没有关联

  1. 中断
  2. 快速中断
  3. 系统错误

 

异步异常感觉更像是MCU里面的一些异常,中断类似于STM32的NVIC中断

 

系统错误也是类似于STM32的一些HARDFAULT、总线fault或者NMI等

 

 

LINUX的异常和MCU也是一样,有一些异常向量表。

 

 

 

异常处理的流程

  1. 把当前的处理器状态保存在寄存器SPSR_EL1程序状态寄存器中
  2. 把返回地址保存在寄存器ELR_EL1异常链接寄存器中
  3. 把处理器状态的DAIF这4个异常掩码位都设置为1.禁止这4种异常
  4. 如果是同步异常或系统错误异常,把生成异常的原因保存在寄存器ESR_EL1异常症状寄存器中
  5. 如果是同步异常,把错误地址保存在寄存器FAR_EL1错误地址寄存器中
  6. 根据向量基准地址寄存器异常类型和生成异常的异常级别额计算出异常向量的虚拟地址,执行异常向量。

 

这段异常处理流程,其实和CORTEX M3的异常处理流程也是有类似的        

 

 

LINUX中断处理

第一层处理函数是中断描述符的成员handle_irq()

第二层处理函数是设备驱动程序注册的处理函数。中断描述符由一个中断处理链表(irq_desc.action),每个中断处理描述符(irq_action)保存设备驱动程序注册的处理函数。因为多个设备可以共享同一个硬件中断号,所以中断处理链表可能挂载多个中断处理描述符。

 

 

源码在kerne/irq/irqdesc.c函数文件里

 

 

 

用来存用户注册的中断处理函数,一个中断可以有多个处理函数 ,当一个中断有多个处理函数,说明这个是共享中断,所谓共享中断就是一个中断的来源有很多,这些来源共享同一个引脚。所以在irq_desc结构体中的action成员是个链表,以action为表头,若是一个以上的链表就是共享中断

struct irq_desc {
    struct irq_data        irq_data;
    unsigned int __percpu    *kstat_irqs;------IRQ的统计信息
    irq_flow_handler_t    handle_irq;--------(1)
    struct irqaction    *action; -----------(2)
    unsigned int        status_use_accessors;-----中断描述符的状态,参考IRQ_xxxx
    unsigned int        core_internal_state__do_not_mess_with_it;----(3)
    unsigned int        depth;----------(4)
    unsigned int        wake_depth;--------(5)
    unsigned int        irq_count;  ---------(6)
    unsigned long        last_unhandled;  
    unsigned int        irqs_unhandled;
    raw_spinlock_t        lock;-----------(7)
    struct cpumask        *percpu_enabled;-------(8)
#ifdef CONFIG_SMP
    const struct cpumask    *affinity_hint;----和irq affinity相关,后续单独文档描述
    struct irq_affinity_notify *affinity_notify;
#ifdef CONFIG_GENERIC_PENDING_IRQ
    cpumask_var_t        pending_mask;
#endif
#endif
    unsigned long        threads_oneshot; -----(9)
    atomic_t        threads_active;
    wait_queue_head_t       wait_for_threads;
#ifdef CONFIG_PROC_FS
    struct proc_dir_entry    *dir;--------该IRQ对应的proc接口
#endif
    int            parent_irq;
    struct module        *owner;
    const char        *name;
} ____cacheline_internodealigned_in_smp

 

在Linux内核中,中断处理流程通常涉及多个函数,其中handle_irq_event_percpu是处理中断事件的关键函数之一。该函数通过调用在request_irq中注册的中断处理程序(ISR)来处理中断事件。具体来说,当CPU接收到一个中断时,会调用handle_irq_event函数,该函数进一步调用handle_irq_event_percpu来处理每个CPU上的中断事件‌

 

 

 

中断描述符的初始化的接口kerne/irq/irqdesc.c函数文件里,在这个文件里有两个Irq的初始化,越往下看越复杂,完全超出了我的能力了,不做内核开发方向的,看这些真的很费劲很难。

 

 

 

此帖出自Linux开发论坛

最新回复

要结合硬件手册,否则很多处理不知道为啥要这样弄。   详情 回复 发表于 5 天前
点赞 关注

回复
举报

1388

帖子

1

TA的资源

五彩晶圆(初级)

沙发
 

楼主让人敬佩呀。。。。。。。。。。。。。。

不做内核开发的方向,还能沉下心来研究。。。。。。。

此帖出自Linux开发论坛

点评

太难了  基本放弃了  完全搞不明白  详情 回复 发表于 2025-1-18 17:38
 
 

回复

7228

帖子

195

TA的资源

五彩晶圆(高级)

板凳
 
hellokitty_bean 发表于 2025-1-17 21:19 楼主让人敬佩呀。。。。。。。。。。。。。。 不做内核开发的方向,还能沉下心来研究。。。。。。。

太难了  基本放弃了  完全搞不明白

此帖出自Linux开发论坛

点评

要结合硬件手册,否则很多处理不知道为啥要这样弄。  详情 回复 发表于 5 天前
 
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

4
 
常见泽1 发表于 2025-1-18 17:38 太难了  基本放弃了  完全搞不明白

要结合硬件手册,否则很多处理不知道为啥要这样弄。

此帖出自Linux开发论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表