arm64架构的linux中断分析(一)

这篇具有很好参考价值的文章主要介绍了arm64架构的linux中断分析(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 中断的概念和作用

当计算机的CPU需要在执行任务的同时响应外部事件时,中断是一种重要的机制。中断是异步事件的一种形式,这是指发起事件与处理事件之间的时间间隔没有固定的模式,而是在不同的时间点发生的。

在计算机系统中,中断可分为软件中断和硬件中断两类。在软件中断中,中断是由CPU执行的一条特殊指令造成的,它用于暂停CPU的正常执行流程,然后转而执行一个内部事件或处理程序。硬件中断则是由硬件设备发出的,它与处理器无关,并向CPU发出中断请求信号。

中断的作用主要有以下几个方面:

  1. 响应外部事件:当外部事件发生时,中断能够及时响应并引导CPU执行事件处理程序,保证事件能够得到及时处理。

  2. 提高系统效率:CPU无需主动地去轮询外部设备是否有数据需要处理,中断机制可以使CPU在处理器时间的同时响应必要的事件处理。

  3. 处理复杂任务:某些外部事件处理需要一段复杂的代码,中断处理程序可以协助CPU快速完成这些复杂任务。

  4. 进行设备驱动:硬件设备的驱动需要中断的支持,来达到与CPU通讯和协调工作的目的。

2. Linux中断处理机制

Linux操作系统具有广泛的应用,它的中断处理机制是实时、高效和可扩展的。Linux中断处理机制采用了事件驱动模型,对中断按照优先级进行排队,以确保最优先处理高优先级事件,同时保证低优先级事件不会被阻塞。下面从中断请求、中断处理和中断完成三个方面介绍Linux中断处理机制。

2.1 中断请求

在Linux中,中断被认为是分离的、独立的事件,因此中断的处理必须是实时的,使用优先级表进行调度和排序。Linux内核实现了基于可插拔中断体系结构的抽象机制,从而可以在处理器和设备机制之间提供更好的耦合性和深入性。这种体系结构允许中断请求线共享,提高了系统的可扩展性和可靠性,提升了系统的响应速度和性能表现。
当一个硬件设备需要处理器的处理时,它将通过硬件 Intline 请求一个中断。中断请求将被系统中断控制器传递,并被处理器接收。 Linux 支持多个中断请求,通常使用 PCI 设备接口来实现。当控制器接收到中断请求后,它会将请求传递给 Linux 中的 IRQ 子系统,于是就有了一个中断。

2.2 中断处理

中断处理是指系统响应中断事件的过程,它通常包含以下几个步骤:

  • 中断调度:中断请求被发送到CPU中心处理器上的中断控制器后,由硬件中断控制器将中断信号传递到内核。Linux内核根据中断向量号找到对应的中断处理程序。
  • 应答中断:内核通过设置正确的输入 / 输出引脚响应中断,这样中断控制器就可以发送指令将中断信息传递给 CPU。
  • 中断上下文的保存:当内核处理中断时,必须保存当前进程运行的上下文,为后续恢复工作做好准备。
  • 中断处理程序运行:中断程序处理中断,执行需要的中断服务程序,并最终返回到主线程。
  • 中断恢复工作:恢复中断执行前的上下文,这包括无序通知的应用程序。

2.3 中断完成

当中断处理完成后,处理器会向中断控制器发送完成中断的信号。中断控制器将中断信号发送回硬件设备。在中断完成的过程中,主要包含以下几个步骤:

  1. 中断状态恢复:在中断处理过程中,处理器会保存中断处理程序执行前的所有中断状态,包括进程的上下文、寄存器和状态字等。因此,在中断处理程序执行结束后,处理器需要通过对这些状态进行恢复,来重新运行之前被中断的进程。

  2. 设备控制器响应:当设备控制器接收到中断完成信号后,将在下一个可用的时钟周期中恢复设备操作,以继续处理新的输入或输出请求。此时,处理器将会准备新的请求或服务,以响应下一次中断请求。

中断完成是中断处理机制的最后一个阶段,通过该阶段可以使得设备控制器继续其后续的工作,同时为下一次中断请求做好准备。

arm64架构的linux中断分析(一)

2.4.中断触发和处理步骤详解

我们以gpio中断位例子讲解一下arm64中断的完整流程,先看看cpu到gpio的硬件上是怎么样的一个关系:
arm64架构的linux中断分析(一)
看到上面这个图片我们可以看到中断触发的流程:外部设备(比如按键)→GPIO控制器→GIC→CPU。
当触发流程走到cpu后,cpu会跳转到中断异常向量表,执行后面的操作:读取GIC信息,了解到是GPIO触发的中断,再读取GPIO控制器的信息,了解到是某一个GPIO的外设导致的,执行这个外设的中断处理函数。
看到上面这个简单的过程,感觉还是很不清晰。

arm64中断初始化,cpu接受到中断后为什么会自动跳转到异常向量表呢?
这是因为linux初始化的时候,会把异常向量表vectors的地址写入到vbar_el1寄存器中,我们linux内核触发了中断,则会自动跳转到vbar_el1这个这个地址上运行。具体初始化可以查看linux内核启动分析(一)。

我们再看看异常向量表是怎么样的,linux的异常向量表代码在arm64\kernel\entry.S:

SYM_CODE_START(vectors)
	kernel_ventry	1, sync_invalid			// Synchronous EL1t
	kernel_ventry	1, irq_invalid			// IRQ EL1t
	kernel_ventry	1, fiq_invalid			// FIQ EL1t
	kernel_ventry	1, error_invalid		// Error EL1t

	kernel_ventry	1, sync				// Synchronous EL1h
	kernel_ventry	1, irq				// IRQ EL1h
	kernel_ventry	1, fiq_invalid			// FIQ EL1h
	kernel_ventry	1, error			// Error EL1h

	kernel_ventry	0, sync				// Synchronous 64-bit EL0
	kernel_ventry	0, irq				// IRQ 64-bit EL0
	kernel_ventry	0, fiq_invalid			// FIQ 64-bit EL0
	kernel_ventry	0, error			// Error 64-bit EL0

#ifdef CONFIG_COMPAT
	kernel_ventry	0, sync_compat, 32		// Synchronous 32-bit EL0
	kernel_ventry	0, irq_compat, 32		// IRQ 32-bit EL0
	kernel_ventry	0, fiq_invalid_compat, 32	// FIQ 32-bit EL0
	kernel_ventry	0, error_compat, 32		// Error 32-bit EL0
#else
	kernel_ventry	0, sync_invalid, 32		// Synchronous 32-bit EL0
	kernel_ventry	0, irq_invalid, 32		// IRQ 32-bit EL0
	kernel_ventry	0, fiq_invalid, 32		// FIQ 32-bit EL0
	kernel_ventry	0, error_invalid, 32		// Error 32-bit EL0
#endif
SYM_CODE_END(vectors)
2.4.1 异常向量表的解读

其实,在 ARM64 体系结构中,异常分为同步异常和异步异常。
同步异常是试图执行指令时生成的异常,或是作为指令的执行结果生成的异常。同步异常包括如下。

  1. 系统调用。异常级别 0 使用 svc指令陷入异常级别 1,异常级别1 使用hv指令陷入异常级别2,异常级别 2 使用 smc指令陷入异常级别 3。
  2. 数据中止,即访问数据时的页错误异常,虚拟地址没有映射到物理地址,或者没有写权限。
  3. 指令中止,即取指令时的页错误异常,虚拟地址没有映射到物理地址,或者没有执行权限。
  4. 栈指针或指令地址没有对齐。
  5. 没有定义的指令。
  6. 调试异常。

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

  1. 中断(normal priority interrupt,IRQ),即普通优先级的中断。
  2. 快速中断(fast interrupt,FIQ),即高优先级的中断。
  3. 系统错误(System Error,SError),是由硬件错误触发的异常,例如最常见的是把脏数据从缓存行写回内存时触发异步的数据中止异常。

当异常发生的时候,处理器需要执行异常的处理程序。存储异常处理程序的内存位置称为异常向量,通常把所有异常向量存放在一张表中,称为异常向量表。对于 ARM64 处理器的异常级别 1、2 和 3,每个异常级别都有自己的异常向量表,异常向量表的起始虚拟地址存放在寄存器 VBAR_ELn(向量基准地址寄存器,Vector Based Address Register)中。每个异常向量表有 16 项,分为 4 组,每组 4项,每项的长度是 128 字节(可以存放32 条指令)中。

我们看到有4组,每一组的4项都是分别表示发生了同步异常,irq,firq和系统错误。这4组的区别就是,第一组表示异常发生在EL0,处理异常的特权等级也是EL0。第二组表示异常发生在ELn(n可以为1,2,3),处理异常的特权等级也是ELn(n可以为1,2,3),但是这里是linux内核,所以我们的特权为EL1,我们可以理解为异常发生在EL1,处理异常的特权等级也是EL1。这两组的共同点是异常的发生和处理在同一个特权级别,不需要进行特区那级别的切换;而后面两组则是异常的发生和处理不在同一个特权级别,需要进行特区那级别的切换。在linux这里就是说,第三组和第四组表示异常发生在EL0,但是异常处理却在EL1,而他们的区别就是,第三组表示异常发生在64位环境下,第四组表示异常发生在32位环境下。
我们现在知道这4组,16项的含义了,我们看fiq都是invalid的,是因为linux不支持fiq,所以没有对fiq异常进行处理。我们也看到第一组都是invalid的,是因为EL0发生了异常,不会在EL0处理,会陷入EL1处理,所以第一组也不需要实现。
第二组第一项kernel_ventry 1, sync ,在这里就是b el1_sync ,也就是跳转到el1_sync函数了。到这里,我们把每一项支持的异常向量跳转函数写成表格就是:

异常向量 跳转的函数
kernel_ventry 1, sync el1_sync
kernel_ventry 1, irq el1_irq
kernel_ventry 1, error el1_error
kernel_ventry 0, sync el0_sync
kernel_ventry 0, irq el0_irq
kernel_ventry 0, error el0_error
kernel_ventry 0, sync_compat, 32 el0_sync_compat
kernel_ventry 0, irq_compat, 32 el0_irq_compat
kernel_ventry 0, error_compat, 32 el0_error_compat

也就是说linux在用户态触发中断会执行el0_irq,在内核态触发中断会执行el1_irq,这两个的代码看下面:

SYM_CODE_START_LOCAL_NOALIGN(el0_irq)
	kernel_entry 0
el0_irq_naked:
	el0_interrupt_handler handle_arch_irq
	b	ret_to_user
SYM_CODE_END(el0_irq)

SYM_CODE_START_LOCAL_NOALIGN(el1_irq)
	kernel_entry 1
	el1_interrupt_handler handle_arch_irq
	kernel_exit 1
SYM_CODE_END(el1_irq)

我么可以看到他们都是执行函数handle_arch_irq函数,最后返回各自的状态。handle_arch_irq在下面的gic控制器的初始化过程中会设置的。

2.4.2 中断亲和性

arm64的每一个cpu都有自己的标号,这个标号记录在mpdir寄存器中,中断的亲和性就是在每一个中断的GICD_IROUTER寄存器中设置affinity。
arm64架构的linux中断分析(一)

2.5 硬件中断号和软件中断号

硬件中断号是中断控制器自己定义的中断号,每一个中断控制器都有0到n不同数量的中断号,用于识别连接到中断控制器的不同的硬件设备发生的中断事件。比如,GIC这个中断控制器,0-15是SGI中断,16-31是PPI中断,32-1023是SPI中断,我们的设备到是连接到SPI中断上的,甚至GPIO中断控制器也是连接到SPI上面的。GPIO中断控制器自己也有这0-n的中断。所以硬件中断号是某一个中断控制器上的硬件标识。

软件中断号,有时候也叫虚拟中断号,是由内核定义的中断号,用于执行内核函数或服务。软件中断号是预定的,由系统中的中断控制器管理。硬件中断号的产生都会分配一个对应的软件中断号。所以软件中断号硬件无关,仅仅是被CPU用来标识一个外设中断,便于系统管理所有的中断。

这样,CPU和终中断控制器在标识中断上就有了一些不同的概念,但是,对于驱动工程师而言,我们和CPU视角是一样的,我们只希望得到一个软件中断号,而不关系具体是那个interrupt controller上的那个硬件中断号。这样一个好处是在中断相关的硬件发生变化的时候,驱动软件不需要修改。因此,linux内核中的中断子系统需要提供一个将硬件中断号映射到软件中断号上来的机制。文章来源地址https://www.toymoban.com/news/detail-502527.html

到了这里,关于arm64架构的linux中断分析(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux系统查看版本、位数(32位或64位)、架构(arm或amd)的命令

    这里是Ubuntu linux系统; 输入命令: 显示: 输入命令: 显示: 输入命令: 显示: 补充:amd (intelx86架构)和arm版本区别。 x86和arm架构定位不同: arm基于精简指令(RISC),本身定位于嵌入式平台,简化了硬件逻辑的设计,减少了晶体管,从而降低功耗,流水线等控制并不复杂

    2024年02月16日
    浏览(39)
  • Linux conan+cmake管理的项目如何进行多架构编译(x86_64及交叉编译arm64)

    Conan 和 CMake 是两个非常流行的跨平台开发工具,它们可以让开发者轻松管理依赖和构建项目,支持多种操作系统和架构。下面是一些关于 conan 和 cmake 的介绍: Conan Conan 是一个用于管理 C++ 依赖项的开源工具。它可以从公共或私有存储库中自动下载和安装依赖项。Conan 可以轻

    2024年02月09日
    浏览(35)
  • 注意避坑:centos7官方版镜像不支持arm架构(docker请求的映像的平台(linux/aamd64)与检测到的主机平台(linux/alm64/v8)不匹配)fauria/vsftpd

    注意是centos7 docker官方版镜像不支持arm架构(FROM centos:7),不是centos7不支持arm 今天基于fauria/vsftpd在我们的arm盒子上做了个docker镜像,但是用镜像run容器的时候提示: 翻译就是: 警告:请求的映像的平台(linux/aamd64)与检测到的主机平台(linux/alm64/v8)不匹配,并且没有请求

    2024年02月08日
    浏览(35)
  • ARM处理器有哪些工作模式和寄存器?各寄存器作用是什么?ARM异常中断处理流程?

    快速学习嵌入式开发其他基础知识? 返回专栏总目录 《嵌入式工程师自我修养/C语言》 Tip📌:鼠标悬停双虚线/句,可获得更详细的描述   ARM处理器有多种工作模式,如下表所示。应用程序正常运行时,ARM处理器工作在 用户模式(User mode) ,当程序运行出错或有中

    2024年02月21日
    浏览(42)
  • 【理解ARM架构】中断处理 | CPU模式

    🐱作者:一只大喵咪1201 🐱专栏:《理解ARM架构》 🔥格言: 你只管努力,剩下的交给时间! 如上图,在上篇文章中本喵主要介绍的是右侧框中的异常,这里开始介绍一下左边框里的中断,中断主要由三部分组成: 中断源: 中断源多种多样,比如GPIO、定时器、UART、DMA等等

    2024年02月05日
    浏览(37)
  • x86架构ubuntu 搭建arm64交叉编译环境及QT编译arm64架构工程

    背景:由于最近项目需要做国产系统适配,很多软件需要重新编译以适配不同架构CPU。 环境: 1、主机win10 64bit   vmware虚拟主机ubuntu1804 64bit 2、vmware虚拟主机已经安装了qt5.14.2及qt_create4.11.1 一、C/C++程序交叉编译 1、交叉编译环境搭建 ①选定编译工具aarch64-linux-gnu ②安装交叉

    2024年02月09日
    浏览(51)
  • Linux 下杀毒软件 clamav-1.0.0.linux.x86_64.rpm 离线安装及测试CentOS7,CentOS6.8,KylinV10 arm架构

    本文主要记录在centos7以及centos6.8版本上安装记录!废话不多说,直接开始操作!后添加KylinV10 arm架构安装记录 1、下载rpm包 https://www.clamav.net/downloads 官网地址 2、上传安装包到服务器并安装 3、创建目录 4、新建日志文件 5、编辑配置conf文件 6、配置库文件 7、创建clamav用户并

    2024年02月13日
    浏览(47)
  • [ARM 汇编]进阶篇—异常处理与中断—2.4.1 异常处理概念

    异常处理简介 在ARM汇编开发中,异常处理和中断是常见的概念,它们是对系统运行过程中出现的特殊情况进行处理的一种机制。异常处理和中断包括硬件异常、软件异常和外部中断等。当处理器遇到这些特殊情况时,它会自动执行相应的处理程序。 异常和中断的分类 复位(

    2024年02月09日
    浏览(40)
  • ARM A64架构TrustZone学习

    本文翻译自文档 Learn the architecture - TrustZone for AArch64 原文链接:https://developer.arm.com/documentation/102418/0101/?lang=en 在本指南中,我们介绍了 TrustZone。TrustZone 通过内置于 CPU 中的硬件强制隔离提供了一种高效的、系统范围的安全方法。 我们涵盖了 TrustZone 添加到处理器架构中

    2024年02月06日
    浏览(35)
  • 交叉编译ARM64架构electron详解

    本文主要参考Electron官方文档中 构建说明 和 构建步骤(Linux) 在amd64环境内构建arm64的electron包。 如果是arm64环境请查看文章arm64架构编译electron长征路 操作系统版本:统信1060 操作系统架构:amd64 内存:32G 如下图: electron版本:v25.9.8 chromium版本:114.0.5735.289 由于llvm编译需要

    2024年02月02日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包