LINUX-内核-中断分析-中断向量表(3)-arm【转】
2017-12-12 17:47
525 查看
转自:http://blog.csdn.net/haolianglh/article/details/51986987
既然更类似MIPS体系,那么自然的ARM体系就存在“异常中断入口”和“异常中断向量表”的概念。
摘自《ARM体系结构与编程》表9-1,如表 4
1所示,ARM的这个异常中断向量表可以是高端向量表,也可以是低端向量表,两者取其一。区别是基地址不同。高端向量是ARM架构可选配置,可以通过硬件外部输入管脚来配置是低端向量还是高端向量,不能通过指令来改变向量的位置,但如果ARM芯片内部有标准ARM协处理器,那么协处理器CP15的寄存器C1的bit13可以用来切换低端和高端向量地址,等于0时为低端向量,等于1时为高端向量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
异常向量表内容是针对ARM的7种异常要采取的不同的处理代码,但是这个异常向量表总size是非常小的,其中每一种异常只有4字节的代码。因此实际上向量表中针对每一种异常的每一个表项都是一句跳转指令或者是使用ldr指令向PC寄存器写入新值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
arm中断概念
在《ARM体系结构与编程》第9章中说到,ARM 中有个概念叫做“异常中断”,也就是包括外部中断在内的各种异常。显然,ARM体系的“异常中断”概念更加接近MIPS体系中的“异常”概念。既然更类似MIPS体系,那么自然的ARM体系就存在“异常中断入口”和“异常中断向量表”的概念。
arm的异常中断向量表
非向量化中断
ARM体系定义了7种异常中断,在《ARM体系结构与编程》第9章的表9.1中标明了这7种异常中断。其中第6中异常中断即是外部中断的统一入口。显然,在ARM中,也类似MIPS一样实行了非向量化的外部中断。应该说RISC类的架构几乎都是采用非向量化中断。向量化异常中断
虽然外部中断没有被向量化,但是异常中断被向量化了。因此,ARM也有一个所谓异常中断向量表。摘自《ARM体系结构与编程》表9-1,如表 4
1所示,ARM的这个异常中断向量表可以是高端向量表,也可以是低端向量表,两者取其一。区别是基地址不同。高端向量是ARM架构可选配置,可以通过硬件外部输入管脚来配置是低端向量还是高端向量,不能通过指令来改变向量的位置,但如果ARM芯片内部有标准ARM协处理器,那么协处理器CP15的寄存器C1的bit13可以用来切换低端和高端向量地址,等于0时为低端向量,等于1时为高端向量。
异常中断向量表的初始化
arm体系在函数early_trap_init()中初始化这个异常中断向量表,相比x86以设置门的方式赋值idt_table,MIPS直接给全局变量exception_handlers[]成员赋值的方式。arm的方式比较另类。其方式是将从__vectors_start开始,直到__vectors_end之间的一段代码给复制到vectors_base地址上,这个vectors_base其实就是0x0000000或者0xffff0000。------------------------------------------------arch/arm/kernel/trap.c void __init early_trap_init(void *vectors_base) { /* 异常向量表 exception vectors的基址 */ unsigned long vectors = (unsigned long)vectors_base; extern char __vectors_start[], __vectors_end[]; 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); . . . }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
异常向量表内容是针对ARM的7种异常要采取的不同的处理代码,但是这个异常向量表总size是非常小的,其中每一种异常只有4字节的代码。因此实际上向量表中针对每一种异常的每一个表项都是一句跳转指令或者是使用ldr指令向PC寄存器写入新值。
------------------------------------------arch/arm/kernel/entry-armv.S .globl __vectors_start __vectors_start: ARM( swi SYS_ERROR0 ) THUMB( svc #0 ) THUMB( nop ) W(b) vector_und + stubs_offset /* 未定义指令 */ W(ldr) pc, .LCvswi + stubs_offset /* 软件中断SWI,系统调用 */ W(b) vector_pabt + stubs_offset /* 指令预取中止 */ W(b) vector_dabt + stubs_offset /* 数据访问中止 */ W(b) vector_addrexcptn + stubs_offset /* 保留 */ W(b) vector_irq + stubs_offset /* 外部中断模式 */ W(b) vector_fiq + stubs_offset /* 快速中断模式 */ .globl __vectors_end __vectors_end:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
初始化大蓝图
下面以海思的Hi3535为例展示arm体系中断初始化的主要流程。相关文章推荐
- LINUX-内核-中断分析-中断向量表(3)-arm
- LINUX-内核-中断分析-中断向量表(1)-x86
- LINUX-内核-中断分析-中断向量表(2)-mips
- linux-2.6.26内核中ARM中断实现详解(3)
- linu型 内核中arm中断流程详细分析
- linux-3.2.36内核启动4-setup_arch中的内存初始化3(arm平台 bootmem_init源码分析)
- arm-Linux中断处理体系结构与处理流程分析
- IA32上Linux内核中断机制分析
- linux-2.6.26内核中ARM中断实现详解(1)
- linux内核中断 ----- tasklet 分析 .
- linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)【转】
- ARM Linux中断分析
- linux-2.6.26内核中ARM中断实现详解(2)
- linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)
- ARM-Linux s3c2440 之中断分析(二)
- linux-2.6.26内核中ARM中断实现详解(1)
- linux-2.6.26内核中ARM中断实现详解
- ARM-Linux——内核启动流程分析
- linux 内核对中断标志的处理(SRCPND 清除)分析
- linux-3.2.36内核启动1-启动参数(arm平台 启动参数的获取和处理,分析setup_arch)