微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Linux中断机制之中断处理

ARM Linux中断机制之中断处理

时间:11-09 来源:互联网 点击:
//现在来看看中断初始化的另一个函数early_trap_init(),该函数在文件arch/arm/kernel/traps.c中实现。

void __init early_trap_init(void)
{

//CONFIG_VECTORS_BASE在autoconf.h中定义(该文件自动成生),值为0xffff0000,
unsigned long vectors = CONFIG_VECTORS_BASE;
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
extern char __kuser_helper_start[], __kuser_helper_end[];
int kuser_sz = __kuser_helper_end - __kuser_helper_start;

/* 异常向量表拷贝到 0x0000_0000(或 0xFFFF_0000) ,
异常处理程序的 stub 拷贝到 0x0000_0200(或 0xFFFF_0200) */
memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);

/* 拷贝信号处理函数 */
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
sizeof(sigreturn_codes));

/* 刷新 Cache,修改异常向量表占据的页面的访问权限*/

flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}

这个函数把定义在 arch/arm/kernel/entry-armv.S 中的异常向量表和异常处理程序的 stub 进行
重定位:异常向量表拷贝到 0xFFFF_0000,异常向量处理程序的 stub 拷贝到 0xFFFF_0200。
然后调用 modify_domain()修改了异常向量表所占据的页面的访问权限,这使得用户态无法
访问该页,只有核心态才可以访问。

arm处理器发生异常时总会跳转到 0xFFFF_0000(设为“高端向量配置”时)处的异常向量
表,因此进行这个重定位工作。

异常向量表,在文件arch/arm/kernel/entry-armv.S 中

.equstubs_offset, __vectors_start + 0x200 - __stubs_start

.globl__vectors_start
__vectors_start:
swiSYS_ERROR0
bvector_und + stubs_offset//复位异常:
ldrpc, .LCvswi + stubs_offset//未定义指令异常:
bvector_pabt + stubs_offset//软件中断异常:
bvector_dabt + stubs_offset//数据异常:
bvector_addrexcptn + stubs_offset//保留:
bvector_irq + stubs_offset//普通中断异常:
bvector_fiq + stubs_offset//快速中断异常:

.globl__vectors_end
__vectors_end:

ARM 处理器发生异常(中断是一种异常)时,会跳转到异常向量表,在向量表中找到相应的异常,并跳转到

该异常处理程序处执行。

stubs_offset,定义为__vectors_start + 0x200 - __stubs_start。

在中断初始化函数early_trap_init()中向量表被拷到0xFFFF_0000处,异常处理程序段被拷到0xFFFF_0200处。

比如此时发生中断异常bvector_irq + stubs_offset 将跳转到中断异常处理程序段去执行,由于vector_irq,

在异常处理程序段__stubs_start到__stubs_end之间此时跳转的位置将是__vectors_start + 0x200 + vector_irq - __stubs_start处。

异常处理程序段如下:

当 ARM 处理器发生异常(中断是一种异常)时,会跳转到异常向量表,在向量表中找到相应的异常,并跳转到

该异常处理程序处执行,这些异常处理程序即是放在以下异常处理程序段中。

.globl__stubs_start
__stubs_start:

//vector_stub是一个宏,它代表有一段程序放在此处。irq, IRQ_MODE, 4是传递给宏vector_stub的参数。
vector_stubirq, IRQ_MODE, 4

//以下是跳转表,在宏vector_stub代表的程序段中要用到该表来查找程序要跳转的位置。

//如果在进入终中断时是用户模式,则调用__irq_usr例程,如果为系统模式,则调用__irq_svc,如果是其他模式,则说明出错了,

//则调用__irq_invalid。

.long__irq_usr@ 0 (USR_26 / USR_32)
.long__irq_invalid@ 1 (FIQ_26 / FIQ_32)
.long__irq_invalid@ 2 (IRQ_26 / IRQ_32)
.long__irq_svc@ 3 (SVC_26 / SVC_32)
.long__irq_invalid@ 4
.long__irq_invalid@ 5
.long__irq_invalid@ 6
.long__irq_invalid@ 7
.long__irq_invalid@ 8
.long__irq_invalid@ 9
.long__irq_invalid@ a
.long__irq_invalid@ b
.long__irq_invalid@ c
.long__irq_invalid@ d
.long__irq_invalid@ e
.long__irq_invalid@ f

vector_stubdabt, ABT_MODE, 8

.。。。。。。

vector_stubpabt, ABT_MODE, 4

。。。。。。

vector_stubund, UND_MODE

。。。。。。

vector_fiq:
disable_fiq
subspc, lr, #4

vector_addrexcptn:
bvector_addrexcptn
.align5

.LCvswi:
.wordvector_swi

.globl__stubs_end
__stubs_end:

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top