微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Linux 中断向量表建立流程

ARM Linux 中断向量表建立流程

时间:11-09 来源:互联网 点击:

地址.
  到了53行,由于之前r0保存的是cp15的control register(c1)的值,这里把r0的值写入r8指向的地址,即cr_alignment=r0.到此为止,我们就看清楚了cr_alignment的赋值过程。
  

让我们回到trap_init()函数,经过上面的分析,我们知道vectors_base返回0xffff0000。函数__trap_init由汇编代码编写,在arch/arm/kernel/entry-arm.S:
    .align5
__stubs_start:
vector_IRQ:
    ...
vector_data:
    ....
vector_prefetch:
    ...
vector_undefinstr:
    ...
vector_FIQ:disable_fiq
    subspc, lr, #4
vector_addrexcptn:
    bvector_addrexcptn
    ...
__stubs_end:
    .equ__real_stubs_start, .LCvectors + 0x200

.LCvectors:swiSYS_ERROR0
    b__real_stubs_start + (vector_undefinstr - __stubs_start)
    ldrpc, __real_stubs_start + (.LCvswi - __stubs_start)
    b__real_stubs_start + (vector_prefetch - __stubs_start)
    b__real_stubs_start + (vector_data - __stubs_start)
    b__real_stubs_start + (vector_addrexcptn - __stubs_start)
    b__real_stubs_start + (vector_IRQ - __stubs_start)
    b__real_stubs_start + (vector_FIQ - __stubs_start)

ENTRY(__trap_init)
    stmfdsp!, {r4 - r6, lr}/* 压栈,保存数据*/

  /* 复制异常向量表(.LCvectors起始的8个地址)到r0指向的地址(异常向量地址),r0就是__trap_init(base)函数调用时传递的参数,不明白的请参考ATPCS*/
    adrr1, .LCvectors@ set up the vectors
    ldmiar1, {r1, r2, r3, r4, r5, r6, ip, lr}
    stmiar0, {r1, r2, r3, r4, r5, r6, ip, lr}

    /* 在异常向量地址后的0x200偏移处,放置散转代码,即__stubs_start~__stubs_end之间的各个异常处理代码*/
    addr2, r0, #0x200
    adrr0, __stubs_start@ copy stubs to 0x200
    adrr1, __stubs_end
1: ldrr3, [r0], #4
    strr3, [r2], #4
    cmpr0, r1
blt1b
LOADREGS(fd, sp!, {r4 - r6, pc})/*出栈,恢复数据,函数__trap_init返回*/

__trap_init函数填充后的向量表如下:
虚拟地址异常 处理代码
0xffff0000reset swi SYS_ERROR0
0xffff0004 undefined b__real_stubs_start + (vector_undefinstr - __stubs_start)
0xffff0008 软件中断 ldrpc, __real_stubs_start + (.LCvswi - __stubs_start)
0xffff000c 取指令异常b__real_stubs_start + (vector_prefetch - __stubs_start)
0xffff0010 数据异常 b__real_stubs_start + (vector_data - __stubs_start)
0xffff0014 reserved b__real_stubs_start + (vector_addrexcptn - __stubs_start)
0xffff0018 irq b__real_stubs_start + (vector_IRQ - __stubs_start)
0xffff001c fiq b__real_stubs_start + (vector_FIQ - __stubs_start)

   当有异常发生时,处理器会跳转到对应的0xffff0000起始的向量处取指令,然后,通过b指令散转到异常处理代码.因为ARM中b指令是相对跳转,而且只有+/-32MB的寻址范围,所以把__stubs_start~__stubs_end之间的异常处理代码复制到了0xffff0200起始处.这里可直接用b指令跳转过去,这样比使用绝对跳转(ldr)效率高。

-------------------------参考资料--------------------
1, 刘淼,嵌入式系统接口设计与Linux驱动程序开发,北京航天航空大学出版社,2006.
2, ARM Architecture Reference Manual, ARM limited,2000.
http://jimmy-lee.blog.hexun.com/cate.aspx?cateid=7311&cate=ARM%26Linux


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

网站地图

Top