当前位置: 首页 > news >正文

arm64异常向量表

arm64异常向量表

  • 1 arm64异常向量表
  • 2 linux arm64异常向量表
  • 3 kernel_ventry宏
  • 4 异常向量表的保存
    • 4. VBAR_ELx寄存器
    • 4.2 __primary_switched
    • 4.3 __primary_switched

1 arm64异常向量表

在这里插入图片描述
When an exception occurs, the processor must execute handler code which corresponds to the exception. The location in memory where the handler is stored is called the exception vector. In the ARM architecture, exception vectors are stored in a table, called the exception vector table. Each Exception level has its own vector table, that is, there is one for each of EL3, EL2 and EL1. The table contains instructions to be executed, rather than a set of addresses. Vectors for individual exceptions are located at fixed offsets from the beginning of the table. The virtual address of each table base is set by the Vector Based Address Registers VBAR_EL3, VBAR_EL2 and VBAR_EL1.
Each entry in the vector table is 16 instructions long. This in itself represents a significant change compared to ARMv7, where each entry was 4 bytes. This spacing of the ARMv7 vector table meant that each entry would almost always be some form of branch to the actual exception handler elsewhere in memory. In AArch64, the vectors are spaced more widely, so that the
top-level handler can be written directly in the vector table.
The base address is given by VBAR_ELn and then each entry has a defined offset from this base address. Each table has 16 entries, with each entry being 128 bytes (32 instructions) in size. The table effectively consists of 4 sets of 4 entries.
Which entry is used depends upon a number of factors:

  • The type of exception (SError, FIQ, IRQ or Synchronous)
  • If the exception is being taken at the same Exception level, the Stack Pointer to be used (SP0 or SPx)
  • If the exception is being taken at a lower Exception level, the execution state of the next lower level (AArch64 or AArch32)
    Considering an example might make this easier to understand.
    If kernel code is executing at EL1 and an IRQ interrupt is signaled, an IRQ exception occurs. This particular interrupt is not associated with the hypervisor or secure environment and is also handled within the kernel, also at SP_EL1, and the SPSel bit is set, so you are using SP_EL1. Execution is therefore from address VBAR_EL1 + 0x280.
    In the absence of LDR PC, [PC, #offset] in the ARMv8-A architecture, you must use more instructions to enable the destination to be read from a table of registers. The choice of spacing of the vectors is designed to avoid cache pollution for typical sized instruction cache lines from vectors that are not being used. The Reset Address is a completely separate address, which is
    IMPLEMENTATION DEFINED, and is typically set by hardwired configuration within the core. This address is visible in the RVBAR_EL1/2/3 register.
    Having a separate exception vector for each exception, either from the current Exception level or from the lower Exception level, gives the flexibility for the OS or hypervisor to determine the AArch64 and AArch32 state of the lower Exception levels. The SP_ELn is used for exceptions generated from lower levels. However, the software can switch to use SP_EL0 inside the
    handler. When you use this mechanism, it facilitates access to the values from the thread in the handler.

2 linux arm64异常向量表

/*                          * Exception vectors.       */                         .pushsection ".entry.text", "ax" .align  11          
SYM_CODE_START(vectors)    kernel_ventry   1, t, 64, sync          // Synchronous EL1t kernel_ventry   1, t, 64, irq           // IRQ EL1t kernel_ventry   1, t, 64, fiq           // FIQ EL1t kernel_ventry   1, t, 64, error         // Error EL1t kernel_ventry   1, h, 64, sync          // Synchronous EL1h kernel_ventry   1, h, 64, irq           // IRQ EL1h kernel_ventry   1, h, 64, fiq           // FIQ EL1h kernel_ventry   1, h, 64, error         // Error EL1h kernel_ventry   0, t, 64, sync          // Synchronous 64-bit EL0kernel_ventry   0, t, 64, irq           // IRQ 64-bit EL0kernel_ventry   0, t, 64, fiq           // FIQ 64-bit EL0kernel_ventry   0, t, 64, error         // Error 64-bit EL0                                                                                                                                        kernel_ventry   0, t, 32, sync          // Synchronous 32-bit EL0kernel_ventry   0, t, 32, irq           // IRQ 32-bit EL0kernel_ventry   0, t, 32, fiq           // FIQ 32-bit EL0kernel_ventry   0, t, 32, error         // Error 32-bit EL0
SYM_CODE_END(vectors)
  • .pushsection “.entry.text”, “ax” 表示要将当前的异常向量表放到.entry.text段,属性为"ax"
  • .align 11表示异常向量表的起始地址要2K对齐(2^11 = 2048),这和VBAR_ELx的寄存器定义是一致的。
  • SYM_CODE_START(vectors) 声明异常向量表

3 kernel_ventry宏

  • kernel_ventry是异常向量表的一部分通用处理宏,会依据参数跳转到不同的异常处理函数,对于kernel_ventry 1, h, 64, irq,则会跳转到el1h_64_irq处理函数流程中。
  • .align 7 表示当前的入口要按照128B对齐的方式去存放,这和异常向量表每个entry的大小为128B是匹配的
	.macro kernel_ventry, el:req, ht:req, regsize:req, label:req.align 7
.Lventry_start\@:.if	\el == 0/** This must be the first instruction of the EL0 vector entries. It is* skipped by the trampoline vectors, to trigger the cleanup.*/b	.Lskip_tramp_vectors_cleanup\@.if	\regsize == 64mrs	x30, tpidrro_el0msr	tpidrro_el0, xzr.elsemov	x30, xzr.endif
.Lskip_tramp_vectors_cleanup\@:.endifsub	sp, sp, #PT_REGS_SIZE
#ifdef CONFIG_VMAP_STACK/** Test whether the SP has overflowed, without corrupting a GPR.* Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)* should always be zero.*/add	sp, sp, x0			// sp' = sp + x0sub	x0, sp, x0			// x0' = sp' - x0 = (sp + x0) - x0 = sptbnz	x0, #THREAD_SHIFT, 0fsub	x0, sp, x0			// x0'' = sp' - x0' = (sp + x0) - sp = x0sub	sp, sp, x0			// sp'' = sp' - x0 = (sp + x0) - x0 = spb	el\el\ht\()_\regsize\()_\label0:/** Either we've just detected an overflow, or we've taken an exception* while on the overflow stack. Either way, we won't return to* userspace, and can clobber EL0 registers to free up GPRs.*//* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */msr	tpidr_el0, x0/* Recover the original x0 value and stash it in tpidrro_el0 */sub	x0, sp, x0msr	tpidrro_el0, x0/* Switch to the overflow stack */adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0/** Check whether we were already on the overflow stack. This may happen* after panic() re-enables interrupts.*/mrs	x0, tpidr_el0			// sp of interrupted contextsub	x0, sp, x0			// delta with top of overflow stacktst	x0, #~(OVERFLOW_STACK_SIZE - 1)	// within range?b.ne	__bad_stack			// no? -> bad stack pointer/* We were already on the overflow stack. Restore sp/x0 and carry on. */sub	sp, sp, x0mrs	x0, tpidrro_el0
#endifb	el\el\ht\()_\regsize\()_\label
.org .Lventry_start\@ + 128	// Did we overflow the ventry slot?.endm

4 异常向量表的保存

异常向量表的保存分为两个部分,一个是主核的启动流程,另一个是副核的启动流程处理的。其处理函数分别为__primary_switched和__primary_switched

4. VBAR_ELx寄存器

VBAR_EL1, Vector Base Address Register (EL1),Holds the vector base address for any exception that is taken to EL1.
在这里插入图片描述

  • Bits [63:11]
    • Vector Base Address. Base address of the exception vectors for exceptions taken to EL1.
    • If the implementation does not support ARMv8.2-LVA, then:
      • If tagged addresses are being used, bits [55:48] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
      • If tagged addresses are not being used, bits [63:48] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
    • If the implementation supports ARMv8.2-LVA, then:
      • If tagged addresses are being used, bits [55:52] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
      • If tagged addresses are not being used, bits [63:52] of VBAR_EL1 must be the same or else the use of the vector address will result in a recursive exception.
        其访问方式如下所示:
  • MRS , VBAR_EL1 读取VBAR_EL1寄存器中保存的异常向量表地址到xt寄存器中
  • MSR VBAR_EL1, 将xt寄存器中保存的异常向量表地址写入VBAR_EL1寄存器中。

4.2 __primary_switched

对于主核的启动流程来说,其处理是如下两步,首先将vectors地址加载到x8寄存器中,随后通过msr指令,将其值写入vbar_el1寄存器中。

  • adr_l x8, vectors // load VBAR_EL1 with virtual
  • msr vbar_el1, x8 // vector table address
/** The following fragment of code is executed with the MMU enabled.**   x0 = __pa(KERNEL_START)*/
SYM_FUNC_START_LOCAL(__primary_switched)adr_l	x4, init_taskinit_cpu_task x4, x5, x6adr_l	x8, vectors			// load VBAR_EL1 with virtualmsr	vbar_el1, x8			// vector table addressisbstp	x29, x30, [sp, #-16]!mov	x29, spstr_l	x21, __fdt_pointer, x5		// Save FDT pointerldr_l	x4, kimage_vaddr		// Save the offset betweensub	x4, x4, x0			// the kernel virtual andstr_l	x4, kimage_voffset, x5		// physical mappingsmov	x0, x20bl	set_cpu_boot_mode_flag// Clear BSSadr_l	x0, __bss_startmov	x1, xzradr_l	x2, __bss_stopsub	x2, x2, x0bl	__pi_memsetdsb	ishst				// Make zero page visible to PTW#if VA_BITS > 48adr_l	x8, vabits_actual		// Set this early so KASAN early initstr	x25, [x8]			// ... observes the correct valuedc	civac, x8			// Make visible to booting secondaries
#endif#ifdef CONFIG_RANDOMIZE_BASEadrp	x5, memstart_offset_seed	// Save KASLR linear map seedstrh	w24, [x5, :lo12:memstart_offset_seed]
#endif
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)bl	kasan_early_init
#endifmov	x0, x21				// pass FDT address in x0bl	early_fdt_map			// Try mapping the FDT earlymov	x0, x20				// pass the full boot statusbl	init_feature_override		// Parse cpu feature overridesmov	x0, x20bl	finalise_el2			// Prefer VHE if possibleldp	x29, x30, [sp], #16bl	start_kernelASM_BUG()
SYM_FUNC_END(__primary_switched)

4.3 __primary_switched

对于副核的启动流程来说,其处理是如下两步,首先将vectors地址加载到x5寄存器中,随后通过msr指令,将其值写入vbar_el1寄存器中。

  • adr_l x5, vectors
  • msr vbar_el1, x5
SYM_FUNC_START_LOCAL(__secondary_switched)mov	x0, x20bl	set_cpu_boot_mode_flagstr_l	xzr, __early_cpu_boot_status, x3adr_l	x5, vectorsmsr	vbar_el1, x5isbadr_l	x0, secondary_dataldr	x2, [x0, #CPU_BOOT_TASK]cbz	x2, __secondary_too_slowinit_cpu_task x2, x1, x3#ifdef CONFIG_ARM64_PTR_AUTHptrauth_keys_init_cpu x2, x3, x4, x5
#endifbl	secondary_start_kernelASM_BUG()
SYM_FUNC_END(__secondary_switched)

相关文章:

arm64异常向量表

arm64异常向量表1 arm64异常向量表2 linux arm64异常向量表3 kernel_ventry宏4 异常向量表的保存4. VBAR_ELx寄存器4.2 __primary_switched4.3 __primary_switched1 arm64异常向量表 When an exception occurs, the processor must execute handler code which corresponds to …...

【测试面试】吐血整理,大厂测试开发岗面试题(1~4面),拿下年40w...

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 自动化测试面试题&am…...

SpringSecurity之权限模块设计

目录 前言 实现思路 代码结构 使用说明 前言 前面我们了解了关于微服务权限设计方案以及J W T的相关介绍&#xff0c;今天我们来聊一下&#xff0c;如何避免自己重复的写相同的代码&#xff0c;一次代码实现&#xff0c;即可完美复制到任何项目中实现权限相关的功能。 实现…...

002_双指针法

1.移除元素 目标&#xff1a;移除数组中的某一个元素 数组的元素在内存地址中是连续的&#xff0c;不能单独删除数组中的某个元素&#xff0c;只能覆盖。 1.1暴力解法 建立两个for循环&#xff0c;当查找到某个元素以后&#xff0c;将此元素后面的元素全部往前移动 时间复…...

超实用的 Linux 高级命令,程序员一定要懂

前言 在运维的坑里摸爬滚打好几年了&#xff0c;我还记得我刚开始的时候&#xff0c;我只会使用一些简单的命令&#xff0c;写脚本的时候&#xff0c;也是要多简单有多简单&#xff0c;所以有时候写出来的脚本又长又臭。 像一些高级点的命令&#xff0c;比如说 Xargs 命令、管…...

AI+明厨亮灶智能算法 yolo

AI明厨亮灶智能算法通过pythonyolo网络模型分析算法&#xff0c;AI明厨亮灶模型算法可接对后厨实现如口罩识别、厨师服穿戴、夜间老鼠监测、厨师帽识别、厨师玩手机打电话识别、抽烟识别等实时分析监测。Python是一种由Guido van Rossum开发的通用编程语言&#xff0c;它很快就…...

gRPC-Go源码解读一 客户端请求链路分析

最近在学习gRPC相关的知识&#xff0c;为啥要学呢&#xff1f;因为一直在用&#xff0c;古人云&#xff0c;“工欲善其事&#xff0c;必先利其器”。为此&#xff0c;花了不少时间阅读gRPC-Go的源码&#xff0c;收货甚多&#xff0c;比如透过服务发现和负载均衡这俩组件来学习复…...

Word控件Spire.Doc for .net 功能详解

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…...

联想服务器配置RAID

一、背景描述 目前有台联想服务器&#xff0c;配置如下&#xff1a; CPU&#xff1a;2颗处理器&#xff0c;40核 内存&#xff1a;512GB 磁盘&#xff1a;2*960GB SATA 4*2.4TB SAS 计划在联想物理机上安装 Vmware 的 ESXi 6.7 虚拟化管理软件&#xff0c;作为虚拟化服务器。…...

C++ 虚函数表

在 C 中&#xff0c;虚函数表&#xff08;Virtual Function Table&#xff0c;简称 vtable&#xff09;是一种用于实现多态性&#xff08;Polymorphism&#xff09;的机制。它是一种编译器和链接器生成的数据结构&#xff0c;用于处理虚函数调用。 虚函数是在基类中声明的&…...

rancher2.7丢失集群信息

使用Docker 单节点安装rancher&#xff0c;然后在rancher中创建了一个k8s的集群。重启rancher所在的虚拟机后&#xff0c;登录rancher发现这是新的实例&#xff0c;集群信息丢失了。但是k8s集群还是好好的。 检查k8s的日志&#xff0c;api server日志会报错 time"2023-0…...

数据库管理-第六十八期 Oracle 23c的其他(20230417)

数据库管理 2023-04-17第六十八期 Oracle 23c的其他1 DGPDB2 无锁并发总结第六十八期 Oracle 23c的其他 由于Oracle 23c的文档相对较少&#xff0c;一是当前文档主要面向开发人员&#xff0c;二是感觉实际内容还在不断增加&#xff0c;主要还有一点就是各种新特性的在官方文档…...

精准关键词获取-行业搜索词分析

SEO关键词的收集通常可以通过以下几种方法&#xff1a; 根据市场价值、搜索词竞争性和企业实际产品特征进行筛选&#xff1a;确定您的关键词列表之前&#xff0c;建议先进行市场分析&#xff0c;了解您的竞争对手、行业状况和目标受众等信息&#xff0c;以更好的了解所需的特定…...

c++学习之c++对c的扩展1

目录 1.面向过程与面向对象的编程 2.面向对象编程的三大特点 3.c对c的扩展&#xff1a; 1.作用域运算符&#xff1a;&#xff1a; 2.命名空间 1.c命名空间&#xff08;namespace&#xff09; 2.命名空间的使用 1.在不同命名空间内可以创建相同的名称 2.命名空间只能在全…...

Redis锁的租约问题

目录Redis的租约问题Redis租约问题的想法Redis租约问题的解决方案Redis的租约问题 首先我们先来说一说什么是Redis的租约问题。   在我们实现Redis分布式锁的时候&#xff0c;我们会出现Redis锁的时间<业务执行执行时间&#xff0c;这其实就是一个典型的租约问题&#xf…...

2023年全国最新高校辅导员精选真题及答案50

百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 94.一般认为&#xff0c;在具有了道德认知和道德情感的情况下&#xff0c;道德行为的产生…...

mall商城之k8s部署-4

文章目录 一、k8s部署应用服务1)master拷贝yaml2)批量修改镜像地址3)批量修改nacos地址3)创建命名空间4)创建取sercet5)配置yaml6)对象存储oss7)查看nacos1、导入配置文件2、修改配置文件8)部署到ms命名空间一、k8s部署应用服务 1)master拷贝yaml #将源码文件 mkdi…...

使用Go语言打造轻量级Web框架

前言 Web框架是Web开发中不可或缺的组件。它们的主要目标是抽象出HTTP请求和响应的细节&#xff0c;使开发人员可以更专注于业务逻辑的实现。在本篇文章中&#xff0c;我们将使用Go语言实现一个简单的Web框架&#xff0c;类似于Gin框架。 功能 我们的Web框架需要实现以下功能…...

【开源项目】BallCat 项目脚手架

简介 &#x1f389;&#x1f389;&#x1f389; 基于 React 和 Ant Design 版本的前端 ballcat-ui-react 已发布&#xff0c;欢迎大家尝鲜使用 BallCat 组织旨在为项目快速开发提供一系列的基础能力&#xff0c;方便使用者根据项目需求快速进行功能拓展。 在以前使用其他后台管…...

KlayGE-004-InputCaps 例子分析

InputCaps处理外部输入的事件 该例子主要由两部分内容&#xff1a; 外部输入事件获取 ​ 可以处理keyboard、mouse、joystick、touch、sensor的输入事件 显示一个ui图标按钮 Input 定义监听事件类型&#xff1a; KlayGE::InputActionDefine actions[] {InputActionDefin…...

组装机经验、软硬件故障排除、网络问题

目录 主板 CPU 内存 显卡 判断显卡好坏的步骤 新买的显卡安装后显示器不亮 电源 其他 网络问题 主板 1.不同主板对于不同数量的内存条安装的位置有要求&#xff0c;要按照主板规定的位置安装不同数量的内存条&#xff0c;特别是服务器主板&#xff0c;否则系统可能起…...

【行为型模式】责任链模式

文章目录1、简介2、结构3、实现方式3.1、案例引入3.2、结构分析3.3、具体实现4、责任链优缺点5、应用场景1、简介 责任链模式(Chain of Responsibility)是一种行为型设计模式&#xff0c;它允许对象在链上依次处理请求&#xff0c;用户只需要将请求发送到责任链上即可&#xf…...

C++命令模式 指挥家:掌控命令模式之美

C指挥家&#xff1a;掌控命令模式之美 (C Conductor: Master the Beauty of Command Pattern一、引言 (Introduction)1.1 命令模式概述 (Overview of Command Pattern)1.2 命令模式的应用场景 (Application Scenarios of Command Pattern)二、命令模式的基本概念 (Basic Concep…...

学会 制作极简搜索浏览器 —— 并将 ChatGPT 接入浏览器

前期回顾 Vue3 Ts Vite pnpm 项目中集成 —— eslint 、prettier、stylelint、husky、commitizen_0.活在风浪里的博客-CSDN博客搭建VIte Ts Vue3项目并集成eslint 、prettier、stylelint、huskyhttps://blog.csdn.net/m0_57904695/article/details/129950163?spm1001.2…...

NumPy 秘籍中文第二版:六、特殊数组和通用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍以下秘籍&#xff1a; 创建通用函数查找勾股三元组用chararray执行字符串操作创建一个遮罩数组忽略负值和极值使用recarray函数创建一…...

各种交叉编译工具链的区别

目录 1 命名规则 2 实例 2.1 arm-none-eabi-gcc 2.2 arm-none-linux-gnueabi-gcc 2.3 arm-eabi-gcc 2.4 armcc 2.5 arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc 3 gnueabi和gnueabihf的区别(硬浮点、软浮点) 4 Linaro公司出品的交叉编译工具链 5 ARM公司出…...

密度聚类算法(DBSCAN)实验案例

密度聚类算法&#xff08;DBSCAN&#xff09;实验案例 描述 DBSCAN是一种强大的基于密度的聚类算法&#xff0c;从直观效果上看&#xff0c;DBSCAN算法可以找到样本点的全部密集区域&#xff0c;并把这些密集区域当做一个一个的聚类簇。DBSCAN的一个巨大优势是可以对任意形状…...

第07章_面向对象编程(进阶)

第07章_面向对象编程(进阶) 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 关键字&#xff1a;this 1.1 this是什么&#xff1f; 在Java中&#xff0c;this关键字不算难理解…...

异常的讲解(2)

目录 throws异常处理 基本介绍 throws异常处理注意事项和使用细节 自定义异常 基本概念 自定义异常的步骤 throw 和throws的区别 本章作业 第一题 第二题 第三题 第四题 throws异常处理 基本介绍 1)如果一个方法(中的语句执行时)可能生成某种异常&#xff0c;但是…...

jvm内存结构

1. 栈 程序计数器 2. 虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区 1.2栈内存溢出 栈帧过多导致栈内存溢出 /*** 演示栈内存溢出 java.lang.StackOverflowError* -Xss256k*/ public class Demo1_2 {private static int count;public static void main(String[] args) {try {meth…...