ARM处理器的异常模式

2023-05-16

1、ARM处理器有各种异常模式,用于应对ARM出现的不同状态。出现异常时,会随即进入相关的异常向量,同时CPSR的寄存器也会设置成具体的模式。

例:当出现中断时,不管是哪种中断,都会跳转到0x18这个总入口地址(也有可能是0xFFFFFF18,看系统初始化的虚拟地址,无所谓),然后通过中断号执行具体的中断注册函数。

同时会把CPSR寄存器设置成相应的模式。

当从一个模式切换到另一个模式的时候,需要把之前模式下的HW context保存起来,比方说从用户态进入内核态,因为新模式下,内存区域划分是不一样的。如下图,各个模式下的通用寄存器是同一份,在两种模式下,可以用来传递信息,但是像sp,lr跟空间相关的寄存器会独立一份。

2、出现异常时,如何进入异常模式

2.1、在内核启动阶段,会对异常向量表完成初始化。

start_kernel
    setup_arch
        early_trap_init
void __init early_trap_init(void *vectors_base)
{
	unsigned long vectors = (unsigned long)vectors_base;
	extern char __stubs_start[], __stubs_end[];
	extern char __vectors_start[], __vectors_end[];
	unsigned i;

	vectors_page = vectors_base;

    ......

	/*
	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
	 * into the vector page, mapped at 0xffff0000, and ensure these
	 * are visible to the instruction stream.
	 */
	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
	memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);

    ......
}

异常向量地址保存在vectors_base变量(CONFIG_VECTORS_BASE=0xffff0000)中。

异常向量地址__vectors_start在entry-armv.S - arch/arm/kernel/entry-armv.S - Linux source code (v5.16.9) - Bootlin实现初始化。

在编译的时候,地址已经确定

grep "__vectors" System.map -nR

启动的时候,可以看到异常向量的地址分布情况。

2.2、出现异常时,跳转到异常向量入口__vectors_start,不同的异常对应着不同的偏移量,从图1可以看出software interrrupt对应着异常向量第三项,即W(ldr)    pc, .L__vectors_start + 0x1000对应着software interrupt的入口。

.L__vectors_start:
	W(b)	vector_rst
	W(b)	vector_und
	W(ldr)	pc, .L__vectors_start + 0x1000
	W(b)	vector_pabt
	W(b)	vector_dabt
	W(b)	vector_addrexcptn
	W(b)	vector_irq
	W(b)	vector_fiq

	.data
	.align	2

	.globl	cr_alignment

 后续会根据宏定义跳转到具体的异常向量处理流程。

	.macro	vector_stub, name, mode, correction=0
	.align	5

vector_\name:
	.if \correction
	sub	lr, lr, #\correction
	.endif

	@
	@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
	@ (parent CPSR)
	@
	stmia	sp, {r0, lr}		@ save r0, lr
	mrs	lr, spsr
	str	lr, [sp, #8]		@ save spsr

	@
	@ Prepare for SVC32 mode.  IRQs remain disabled.
	@
	mrs	r0, cpsr
	eor	r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
	msr	spsr_cxsf, r0

	@
	@ the branch table must immediately follow this code
	@
	and	lr, lr, #0x0f
 THUMB(	adr	r0, 1f			)
 THUMB(	ldr	lr, [r0, lr, lsl #2]	)
	mov	r0, sp
 ARM(	ldr	lr, [pc, lr, lsl #2]	)
	movs	pc, lr			@ branch to handler in SVC mode
ENDPROC(vector_\name)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARM处理器的异常模式 的相关文章

随机推荐

  • NVIDIA刷机+部署ROS操作指南

    说明 xff1a Ubuntu18 04 43 ROS melodic 一 NVIDIA刷机操作步骤 准备工作 xff1a 准备一台台式机作为主机 xff0c 且确保安装了ubuntu双系统或者虚拟机 xff0c 再为NVIDIA控制器准备
  • 权限认证基础:区分Authentication,Authorization以及Cookie、Session、Token

    1 认证 Authentication 和授权 Authorization 的区别是什么 xff1f 这是一个绝大多数人都会混淆的问题 首先先从读音上来认识这两个名词 xff0c 很多人都会把它俩的读音搞混 xff0c 所以我建议你先先去查
  • 22从零开始学Java之你知道return、break与continue的区别吗?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套项目资料 https github com SunLtd LearnJ
  • 23从零开始学Java之foreach循环该怎么用?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套项目资料 https github com SunLtd LearnJ
  • 24从零开始学Java之如何正确地使用一维数组

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 25从零开始学Java之数组扩容与数组拷贝的实现过程与原理分析

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 26从零开始学Java之如何对数组进行排序与二分查找?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 配套开源项目资料 https github com SunLtd Lear
  • 27从零开始学Java之详解复杂的二维数组与多维数组

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在前几篇文章中 xff0c 壹哥给大家介绍了Java里的一维数组 x
  • 28从零开始学Java之面向对象和面向过程到底有哪些区别?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 壹哥相信 xff0c 经过你对前面文章中技术点的学习 xff0c 现
  • 29从零开始学Java之如何正确创建Java里的类?

    作者 xff1a 孙玉昌 xff0c 昵称 一一哥 xff0c 另外 壹壹哥 也是我哦 千锋教育高级教研员 CSDN博客专家 万粉博主 阿里云专家博主 掘金优质作者 前言 在上一篇文章中 xff0c 壹哥给大家介绍了面向对象和面向过程的概念
  • 全面图解路由器接口及连接(图)

    路由器所在的网络位置比较复杂 xff0c 既可是内部子网边缘 xff0c 也可位于内 外部网络边缘 同时为了实现强大的适用性 xff0c 它需要连接各种网络 xff0c 这样 xff0c 它的接口也就必须多种多样 对于这些 xff0c 不要
  • blktrace,blkparse,btt工具的制作和使用

    1 软件包交叉编译安装 1 1 blktrace源码下载路径 https git kernel dk cgit blktrace 1 2 源码安装 tar zxvf blktrace 1 2 0 tar gz cd blktrace 1 2
  • cartographer之ceres编译

    1 首先下载ceres xff1b 2 进入ceres目录 xff1b 3 mkdir build amp amp cd build 4 cmake DEIGENSPARSE 5 make 6 sudo make install
  • 一个空文件夹和空文件占多少空间?

    用于显示文件夹和文件大小的命令 span class token function du span h 显示目前在 Linux 系统上的文件系统磁盘使用情况统计 span class token function df span i 一 问
  • 虚拟地址如何访问到物理地址

    环境 xff1a 32bit CPU 一 通过二级页表映射的方式访问物理地址 1 取一级页表的基地址Abase1 2 取虚拟地址的前12bit 31 20 地址O1 3 计算得到新地址Apgd 61 Abase1 amp 0xFFFFF00
  • 添加自定义的section

    一 基本知识点 编译出来的程序 xff08 o so exe ko等等 xff09 都是以elf格式进行排列保存的 elf文件分析情况 xff1a https blog csdn net edonlii article details 87
  • 如何打印堆栈

    一 打印堆栈可以方便问题定位 xff0c 找到具体的函数调用流程 二 打印堆栈的方法 2 1 用户态 include lt stdio h gt include lt stdlib h gt include lt stddef h gt i
  • 内存飞踩问题的几点思考

    1 程序编译 xff0c 链接后生成二进制可执行程序 二进制可执行文件以elf格式实现排列 可以通过readelf S xxxx查看具体section的划分 xff0c 粗略划分如下图所示 在这些section中 xff0c 代码段是只读的
  • CFS调度算法

    1 CFS调度算法 xff0c 顾名思义就是完全公平调度策略 比方说 xff0c 调度延迟时间是10ms xff0c 存在两个进程A和B xff0c 那么两个进程分别占用CPU的时间是5ms 然而 xff0c 阶级总是存在的 xff0c 毕
  • ARM处理器的异常模式

    1 ARM处理器有各种异常模式 xff0c 用于应对ARM出现的不同状态 出现异常时 xff0c 会随即进入相关的异常向量 xff0c 同时CPSR的寄存器也会设置成具体的模式 例 xff1a 当出现中断时 xff0c 不管是哪种中断 xf