arm64--异常处理与中断处理

一、异常等级

EL0 非特权模式,用于运行应用程序

EL1为特权模式,用于运行操作系统内核

EL2用于运行虚拟化管理程序

EL3用于运行安全世界的管理程序

二、同步异常与异步异常

1. 同步异常:处理器执行某条指令而直接导致的异常,往往需要在异常函数里处理该异常之后,处理器才能继续运行,常见的同步异常如下:

  • 尝试访问异常等级不恰当的寄存器

  • 尝试执行关闭或没有定义的指令

  • 使用没有对齐的SP

  • 尝试执行与PC指针没有对齐的指令

  • 软件产生的异常,如执行SVC,HVC或SMC指令

  • 地址翻译或者权限等导致的数据异常

  • 地址翻译或者权限等导致的指令异常

  • 调试导致的异常,如断点异常,观察点异常,软件单步异常等

2. 异步异常:异常触发的原因与处理器当前正在执行的指令无关的异常,中断属于异步异常的一种,常见的异步异常包括物理中断和虚拟中断

  • 物理中断分为3种:分别是SError、IRQ、FIQ

  • 虚拟中断分为3种:分别是vSError、vIRQ、vFIQ

三、异常处理与返回

  1. 异常入口

处理器检测到异常后自动做的事

  • 把PSTATE寄存器的值保存到对应目标异常等级的SPSR_ELx中

  • 把返回等级保存到对应目标异常等级的ELR_RLx中

  • 把PSTATE寄存器中的D、A、I、F标志位都设置为1,相当于把调试异常,SError、IRQ、FIQ都关闭

  • 对于同步异常,要分析异常的原因,把具体的原因写入ESR_ELx中

  • 切换SP寄存器未目标等级的SP_ELx或者SP_EL0

  • 从异常发生现场的异常等级切换到对应目标异常等级,然后跳转到异常向量表中

操作系统做的事

  • 从中断向量表开始,根据异常发生的类型,跳转到合适的异常向量表。异常向量表的每个项都会保存一条跳转指令,然后跳转到恰当的异常处理函数并处理异常

2. 异常返回

当操作系统的异常处理完成后,执行一条ERET指令即可从异常返回,这条指令会自动处理如下工作

  • 从ELR_EL中恢复PC指针

  • 从SPSR_ELx中恢复PSTATE寄存器的状态

四、异常处理的路由 SCR_EL3

HCR_EL2

栈的选择 我们可以通过SPSel寄存器来配置SP。SPSel寄存器中的SP字段设置为0表示所有的EL中使用SP_EL0作为栈指针寄存器,设置为1表示使用SP_ELx作为栈指针寄存器 ARMV8异常向量表

ARMV8向量表有如下特点

  • 除EL0之后,每个EL都有自己的异常向量表

  • 异常向量表的基地址需要设置到VBAR_ELx中

  • 异常向量表的起始地址必须以2KB字节对齐

  • 每个表项可以存放32条指令,一共128字节

从EL2切换到EL1相关寄存器

 #define BAD_SYNC        0
#define BAD_IRQ         1
#define BAD_FIQ         2
#define BAD_ERROR       3
/*处理无效的异常向量*/.macro inv_entry el, reason//kernel_entry elmov x0, spmov x1, #\reasonmrs x2, esr_el1b bad_mode.endm
/*vector table entry每个表项是128字节, align 7表示128字节对齐*/.macro vtentry label.align 7b \label.endm
/** Vector Table** ARM64的异常向量表一共占用2048个字节* 分成4组,每组4个表项,每个表项占128字节* 参见ARMv8 spec v8.6第D1.10节* align 11表示2048字节对齐*/
.align 11
.global vectors
vectors:/* Current EL with SP0当前系统运行在EL1时使用EL0的栈指针SP这是一种异常错误的类型*/vtentry el1_sync_invalidvtentry el1_irq_invalidvtentry el1_fiq_invalidvtentry el1_error_invalid/* Current EL with SPx当前系统运行在EL1时使用EL1的栈指针SP这说明系统在内核态发生了异常Note: 我们暂时只实现IRQ中断*/vtentry el1_sync_invalidvtentry el1_irq_invalidvtentry el1_fiq_invalidvtentry el1_error_invalid/* Lower EL using AArch64在用户态的aarch64的程序发生了异常*/vtentry el0_sync_invalidvtentry el0_irq_invalidvtentry el0_fiq_invalidvtentry el0_error_invalid/* Lower EL using AArch32在用户态的aarch32的程序发生了异常*/vtentry el0_sync_invalidvtentry el0_irq_invalidvtentry el0_fiq_invalidvtentry el0_error_invalid
el1_sync_invalid:inv_entry 1, BAD_SYNC
el1_irq_invalid:inv_entry 1, BAD_IRQ
el1_fiq_invalid:inv_entry 1, BAD_FIQ
el1_error_invalid:inv_entry 1, BAD_ERROR
el0_sync_invalid:inv_entry 0, BAD_SYNC
el0_irq_invalid:inv_entry 0, BAD_IRQ
el0_fiq_invalid:inv_entry 0, BAD_FIQ
el0_error_invalid:inv_entry 0, BAD_ERROR

五、中断处理

#define S_FRAME_SIZE 272 /* sizeof(struct pt_regs)  // */
#define S_X0 0 /* offsetof(struct pt_regs, regs[0]) // */
#define S_X1 8 /* offsetof(struct pt_regs, regs[1]) // */
#define S_X2 16 /* offsetof(struct pt_regs, regs[2])    // */
#define S_X3 24 /* offsetof(struct pt_regs, regs[3])    // */
#define S_X4 32 /* offsetof(struct pt_regs, regs[4])    // */
#define S_X5 40 /* offsetof(struct pt_regs, regs[5])    // */
#define S_X6 48 /* offsetof(struct pt_regs, regs[6])    // */
#define S_X7 56 /* offsetof(struct pt_regs, regs[7])    // */
#define S_X8 64 /* offsetof(struct pt_regs, regs[8])    // */
#define S_X10 80 /* offsetof(struct pt_regs, regs[10])  // */
#define S_X12 96 /* offsetof(struct pt_regs, regs[12])  // */
#define S_X14 112 /* offsetof(struct pt_regs, regs[14]) // */
#define S_X16 128 /* offsetof(struct pt_regs, regs[16]) // */
#define S_X18 144 /* offsetof(struct pt_regs, regs[18]) // */
#define S_X20 160 /* offsetof(struct pt_regs, regs[20]) // */
#define S_X22 176 /* offsetof(struct pt_regs, regs[22]) // */
#define S_X24 192 /* offsetof(struct pt_regs, regs[24]) // */
#define S_X26 208 /* offsetof(struct pt_regs, regs[26]) // */
#define S_X28 224 /* offsetof(struct pt_regs, regs[28]) // */
#define S_FP 232 /* offsetof(struct pt_regs, regs[29])  // */
#define S_LR 240 /* offsetof(struct pt_regs, regs[30])  // */
#define S_SP 248 /* offsetof(struct pt_regs, sp)    // */
#define S_PC 256 /* offsetof(struct pt_regs, pc)    // */
#define S_PSTATE 264 /* offsetof(struct pt_regs, pstate)    // */
#define BAD_SYNC        0
#define BAD_IRQ         1
#define BAD_FIQ         2
#define BAD_ERROR       3.macro kernel_entrysub sp, sp, #S_FRAME_SIZE/*保存通用寄存器x0~x29到栈框里pt_regs->x0~x29*/stp x0, x1, [sp, #16 *0]stp x2, x3, [sp, #16 *1]stp x4, x5, [sp, #16 *2]stp x6, x7, [sp, #16 *3]stp x8, x9, [sp, #16 *4]stp x10, x11, [sp, #16 *5]stp x12, x13, [sp, #16 *6]stp x14, x15, [sp, #16 *7]stp x16, x17, [sp, #16 *8]stp x18, x19, [sp, #16 *9]stp x20, x21, [sp, #16 *10]stp x22, x23, [sp, #16 *11]stp x24, x25, [sp, #16 *12]stp x26, x27, [sp, #16 *13]stp x28, x29, [sp, #16 *14]/* x21: 栈顶 的位置*/add     x21, sp, #S_FRAME_SIZEmrs     x22, elr_el1mrs     x23, spsr_el1/* 把lr保存到pt_regs->lr, 把sp保存到pt_regs->sp位置*/stp     lr, x21, [sp, #S_LR]/* 把elr_el1保存到pt_regs->pc中把spsr_elr保存到pt_regs->pstate中*/stp     x22, x23, [sp, #S_PC].endm.macro kernel_exit/* 从pt_regs->pc中恢复elr_el1,从pt_regs->pstate中恢复spsr_el1*/ldp     x21, x22, [sp, #S_PC]           // load ELR, SPSRmsr     elr_el1, x21                    // set up the return datamsr     spsr_el1, x22ldp     x0, x1, [sp, #16 * 0]ldp     x2, x3, [sp, #16 * 1]ldp     x4, x5, [sp, #16 * 2]ldp     x6, x7, [sp, #16 * 3]ldp     x8, x9, [sp, #16 * 4]ldp     x10, x11, [sp, #16 * 5]ldp     x12, x13, [sp, #16 * 6]ldp     x14, x15, [sp, #16 * 7]ldp     x16, x17, [sp, #16 * 8]ldp     x18, x19, [sp, #16 * 9]ldp     x20, x21, [sp, #16 * 10]ldp     x22, x23, [sp, #16 * 11]ldp     x24, x25, [sp, #16 * 12]ldp     x26, x27, [sp, #16 * 13]ldp     x28, x29, [sp, #16 * 14]/* 从pt_regs->lr中恢复lr*/ldr     lr, [sp, #S_LR]add     sp, sp, #S_FRAME_SIZE           // restore speret.endm
/*处理无效的异常向量*/.macro inv_entry el, reason//kernel_entry elmov x0, spmov x1, #\reasonmrs x2, esr_el1b bad_mode.endm
/*vector table entry每个表项是128字节, align 7表示128字节对齐*/.macro vtentry label.align 7b \label.endm
/** Vector Table** ARM64的异常向量表一共占用2048个字节* 分成4组,每组4个表项,每个表项占128字节* 参见ARMv8 spec v8.6第D1.10节* align 11表示2048字节对齐*/
.align 11
.global vectors
vectors:/* Current EL with SP0当前系统运行在EL1时使用EL0的栈指针SP这是一种异常错误的类型*/vtentry el1_sync_invalidvtentry el1_irq_invalidvtentry el1_fiq_invalidvtentry el1_error_invalid/* Current EL with SPx当前系统运行在EL1时使用EL1的栈指针SP这说明系统在内核态发生了异常Note: 我们暂时只实现IRQ中断*/vtentry el1_sync_invalidvtentry el1_irqvtentry el1_fiq_invalidvtentry el1_error_invalid/* Lower EL using AArch64在用户态的aarch64的程序发生了异常*/vtentry el0_sync_invalidvtentry el0_irq_invalidvtentry el0_fiq_invalidvtentry el0_error_invalid/* Lower EL using AArch32在用户态的aarch32的程序发生了异常*/vtentry el0_sync_invalidvtentry el0_irq_invalidvtentry el0_fiq_invalidvtentry el0_error_invalid
el1_sync_invalid://inv_entry 1, BAD_SYNCkernel_entrymov x0, spmov x1, 0mrs x2, esr_el1bl bad_modekernel_exit
el1_irq_invalid:inv_entry 1, BAD_IRQ
el1_fiq_invalid:inv_entry 1, BAD_FIQ
el1_error_invalid:inv_entry 1, BAD_ERROR
el0_sync_invalid:inv_entry 0, BAD_SYNC
el0_irq_invalid:inv_entry 0, BAD_IRQ
el0_fiq_invalid:inv_entry 0, BAD_FIQ
el0_error_invalid:inv_entry 0, BAD_ERROR
el1_irq:kernel_entrybl irq_handlekernel_exit
//string_test:
//  .string "t"
.global trigger_alignment
trigger_alignment:ldr x0, =0x80002str wzr, [x0]ret

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/410087.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有效提高媒体曝光率,智能推荐为什么是“最大的计算系统之一”?

导语:我认为很少有人意识到,推荐系统是世界上构想过的最大的计算系统之一。——Jensen Huang  在信息过载的时代背景下,智能推荐系统已广泛应用于电子商务、社交媒体、新闻资讯、视频音乐、旅游出行等领域,为用户提…

力扣经典题目之->单值二叉树(递归判断)

一:题目 本博客采用此模型: 二:思路 单值二叉树即所有值相等的二叉树 1:递归的大事化小思路即: 将当前节点与它的左右子节点进行比较,如果不相等,则直接返回false。如果相等,则递归…

记一次 .NET某实验室自动进样系统 崩溃分析

一:背景 1. 讲故事 前些天有位朋友在微信上联系到我,说他们的程序在客户那边崩掉了,让我帮忙看下怎么回事,dump也拿到了,那就上手分析吧。 二:WinDbg 分析 1. 哪里的崩溃 既然是程序的崩溃&#xff0c…

基于状态机实现WIFI模组物联网

1.0 状态机框架原理 如果成功的话就连接热点,如果失败就返回AT通信检查,如果AT通信检查还是失败就放回硬件复位这个状态,如果热点链接成功,就连接MQTT指令,如果失败就返回AT通信检查,如果成功就连接云平台通…

MySQL集群技术

一、MySQL部署 1.源码编译 实验环境为rhel7 安装依赖性 [rootmysql-node1 ~]# yum install cmake gcc-c openssl-devel \ ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el9_4.x86_64.rpm rpcgen.x86_64 -y [rootmysql-node1 ~]# tar zxf mysql-boost-5.7.44.tar.gz 源码…

达梦数据库的系统视图v$object_usage

达梦数据库的系统视图v$object_usage 在达梦数据库(DM Database)中,V$OBJECT_USAGE 视图提供了关于数据库对象的使用情况和统计信息。这些对象可以包括表、索引、视图、存储过程等。通过 V$OBJECT_USAGE 视图,数据库管理员可以监…

贵金属市场展望:黄金独领风骚,钯金、铂金与白银承压

黄金新高可期,避险魅力不减 黄金市场持续升温,近期价格屡创新高。随着全球经济不确定性增加及美联储降息预期的增强,黄金的避险属性得到进一步凸显。市场普遍预期,若美联储在年内维持宽松货币政策,黄金价格有望继续上扬…

新迪天工®看图,专业的三维CAD看图工具

替代专业CAD软件,方便查看各种三维和二维CAD图纸 新迪天工看图是一款功能强大的三维模型和二维图纸查看工具,能帮助制造企业以较低的成本、较高的数据安全性实现产品设计数据的跨业务浏览和交互。 应用场景 1、设计图纸评审 可直接对三维模型和二维…

【数据结构】—— 树和二叉树

1、树的概念2、树的相关术语3、树的常见表示方法4、树的实际应用5、二叉树的相关概念和性质6、二叉树的顺序存储(堆)6.1 堆的概念6.2 堆的结构和接口6.3 堆的初始化和销毁6.4 堆的插入6.5 堆的删除6.5 取堆顶数据6.6 获取有效节点个数6.7 判空6.8 源代码…

高并发业务下的库存扣减技术方案设计

扣减库存需要查询库存是否足够: 足够就占用库存不够则返回库存不足(这里不区分库存可用、占用、已消耗等状态,统一成扣减库存数量,简化场景) 并发场景,若 查询库存和扣减库存不具备原子性,就可能超卖&…

动态内存管理函数malloc,calloc,realloc,free

malloc 函数原型:void* malloc(size_t size); 这个函数向内存申请一块连续可用的size大小的空间,并返回指向这快空间的指针。如果开辟成功,则返回一个指向开辟好空间的指针。如果开辟失败,则返回一个NULL指针,因此ma…

Facebook AI策略全解:从数据分析到智能推荐的成功秘诀

在数字化时代,人工智能(AI)已成为推动科技发展的核心力量。Facebook,作为全球领先的社交网络平台,正通过先进的AI策略来优化用户体验和平台运营。从数据分析到智能推荐,Facebook的AI策略涵盖了多个方面&…

Git 分支操作全解析:创建、切换、合并、删除及冲突解决

“ 在现代软件开发中,高效的版本控制是确保项目成功的关键。Git 提供了强大的分支管理功能,使得开发者能够独立地进行功能开发、修复 bug 和进行紧急修补。本文将深入探讨 Git 分支的基本操作,包括创建、切换、合并和删除分支,同时…

Linux基础 - yum、rzsz、vim 使用与配置、gcc/g++的详细解说

目录 一、Linux 软件包管理器 yum A.什么是软件包? B.关于rzsz,yum的配置 1.安装 sz,rz 命令: a.执行命令sz可将linux中的文件传输到Windows中 b.执行rz命令可将Windows中的文件传输到linux 2.scp XXX.tgz 用户名另一台lin…

免费高画质提取PPT/Word/Excel中的图片工具

下载地址:https://pan.quark.cn/s/134ccc35b8a2 软件简介: 好不容易搞到一个几十上百MB的ppt,想导出里面的图片进行二次加工,却被ppt超低画质的图片另存为功能劝退,明知里面全是高清图片,走时却是两手空空…

1系-8系铝合金材料的成分特性及应用详解

1系-8系铝合金材料的成分特性及应用详解 铝合金概述 铝合金的定义铝合金是一种以铝为基体,通过添加一定量的其他合金化元素(如铜、锰、硅、镁、锌等)形成的合金材料。由于合金元素的加入,铝合金在保持铝的轻质、良好导电导热性等基…

langchain入门系列之六 使用langchain构建PDF解析助手

本文将介绍如何使用langchain构建一个pdf解析助手,在此文中你将学习到langchain如何与web应用(fastapi)相结合,向量持久化等知识,话不多说,现在开始。 安装环境 pip install fastapi pip install python-dotenv pip install uv…

漫步者这款耳机怎么样吗?南卡、漫步者、Cleer公认畅销款式测评!

目前市场上开放式耳机品牌众多,选择时需要充分了解,但即便如此,也难以完全避免购买到质量不佳的产品。作为一位专注于数码产品测评的博主,我对开放式耳机有深入的研究。最近,我收到了许多关于漫步者、南卡、Cleer等品牌…

Flutter-自适用高度PageView

需求 在 Flutter 中,PageView 是一个非常常用的组件,能够实现多个页面的滑动切换。然而,默认的 PageView 高度是固定的,这在展示不同高度的页面时,可能会导致不必要的空白或内容裁剪问题。为了使 PageView 能够根据每…

OpenMax算法详解:深度学习中的高效开集识别技术

OpenMax算法详解:深度学习中的高效开集识别技术 在深度学习领域,模型的识别能力往往受限于其训练数据集的范畴。传统的分类模型,如卷积神经网络(CNN)或循环神经网络(RNN),通常被设计…