目录
1. 前言
本专题我们开始学习进程管理部分。本文主要参考了《奔跑吧, Linux内核》、ULA、ULK的相关内容。
本专题记录ARM架构下中断是如何管理的,Linux内核中的中断管理机制是如何设计与实现的,以及常用的下半部机制,如软中断、tasklet、workqueue等。本文及后续中断相关笔记均以qemu 5.0.0内嵌平台为例,中断控制器采用GIC-400控制器,支持GIC version2技术规范。本文开始介绍ARM64的中断处理过程,先从底层硬件中断的处理过程开始。
kernel版本:5.10
平台:arm64
注:
为方便阅读,正文标题采用分级结构标识,每一级用一个"-“表示,如:两级为”|- -", 三级为”|- - -“
2. arm64中断基础
Exception levels
The Armv8-A architecture defines a set of Exception levels, EL0 to EL3, where:
- If ELn is the Exception level, increased values of n indicate increased software execution privilege.
- Execution at EL0 is called unprivileged execution.
- EL2 provides support for virtualization.
- EL3 provides support for switching between two Security states, Secure state and Non-secure state
arm64异常分类
- Synchronous exception.
- IRQ.
- FIQ
- SError.
注:其中同步异常又需要根据ESR_ELx查看具体是何种同步异常
arm64中断处理相关寄存器
- The general purpose registers, R0-R30:通用寄存器在处理基本指令集的指令时使用。它包括31个通用寄存器,R0-R30。
这些寄存器可以作为31个64位寄存器X0-X30或31个32位寄存器W0-W30访问。 - The stack pointer registers:栈指针寄存器,每个exception level一个,SP_EL0,SP_EL1必须实现,SP_EL2,SP_EL3根据EL2,EL3是否实现来决定;
- The SIMD and floating-point registers, V0-V31:SIMD and floating-point register bank comprises 32 quadword (128-bit) registers, V0-V31;
- Saved Program Status Registers (SPSRs):每个exception level一个(SPSR_ELx, x=1,2,3),用于保存发生异常时的exception level的PE状态;
- Exception Link Registers (ELRs):异常链接寄存器,保存了异常返回地址,每个exception level一个(ELR_ELx,x=1,2,3);
- Exception Syndrome Register (ESR):保存了异常的原因,每个exception level一个(ESR_ELx, x=1,2,3)
- Vector Base Address Register (VBAR):exception level的向量表基址,每个exception level一个(VBAR_ELx,x=1,2,3);
中断发生时硬件处理过程
- 保存PSTATE 数据到SPSR_ELx,(x = 1,2,3),在返回异常现场的时候,可以使用SPSR_ELx来恢复PE的状态
- PSTATE寄存器里的DAIF域设置为1,相当于提哦是异常,系统错误,IRQ以及FIQ都关闭(这防止了中断嵌套);
- 保存异常进入地址到ELR_ELx,同步异常(und/abt等)是当前地址,而异步异常(irq/fiq等)是下一条指令地址,在返回异常现场的时候,可以使用ELR_ELx来恢复PC值
- 保存异常原因信息到ESR_ELx, ESR_ELx.EC代表Exception Class;
- PE根据目标EL的异常向量表中定义的异常向量地址强制跳转到异常处理程序,跳转到哪个EL使用哪个向量偏移地址又路由关系决定;
- 堆栈指针SP的使用由目标EL决定,(SPSR_ELx.M[0] == 1) ? h(ELx): t(EL0);
注:用户态(EL0)不能处理异常,当异常发生在用户态时,异常级别(EL)会发生切换,默认切换到EL1(内核态),所以大部分的异常都被路由到EL1来处理;
路由规则
在不同的exception level, excution mode下, 发生exception时会被路由到不同的exception level,路由的规则是只会向更高的exception level路由,不能反向。相关规则可参考ARM文档
异常向量表

- 每个exception level都有自己的异常向量表,异常向量表保存了arm64发生各种异常时的不同向量,分别对应不同的exception handler,每个exception handler的大小可以为0x80(128)字节;
- arm64有三个异常向量表基址寄存器VBAR_ELX,分别是VBAR_EL1,VBAR_EL2,VBAR_EL3,它们分别记录了三种不同exception level的向量表基址,通过VBAR_ELx可以找到对应exception level的异常向量表。通过vector base address + offset得到具体的exception handler;
- 前面我们说过根据路由规则会使得从一种excepiton level路由到target exception level,VBAR就是记录了target exception level的异常向量表基址,举例来讲,EL0下发生异常路由到EL1,则会跳转到VBAR_EL1指示的异常向量表,进一步根据异常类型计算VBAR_EL1 + offset执行对应的exception handler.
- 如上表,根据发生异常时的exception level、使用的sp、路由的target exception level,可以将异常类型分为四类:
(1)异常发生在当前级别且使用SP_EL0(EL0级别对应的堆栈指针),即发

本文深入探讨了ARM64架构下的中断处理机制,包括Exception Levels、异常分类、中断处理相关寄存器以及硬件中断处理流程。介绍了中断向量表的结构和内核空间中断异常的处理流程,涉及kernel_entry、irq_handler和kernel_exit等关键步骤。内容覆盖了异常向量表的组织、异常返回地址和状态保存,并讨论了EL1下的中断异常处理。
最低0.47元/天 解锁文章
933

被折叠的 条评论
为什么被折叠?



