kernel里异常vector table define在如下位置,(1)/(2)/(3)/(4)部分分别对应上面table中的第1、2、3、4行。
一个vector占128字节,在该vector里,会有branch指令跳转到对应的exception handler。
kernel_ventry开头就是.align 7,所以每个vector size是128 byte对齐的。
entry.S
.align 11 ENTRY(vectors) (1) kernel_ventry 1, sync_invalid // Synchronous EL1t kernel_ventry 1, irq_invalid // IRQ EL1t kernel_ventry 1, fiq_invalid // FIQ EL1t kernel_ventry 1, error_invalid // Error EL1t (2) kernel_ventry 1, sync // Synchronous EL1h kernel_ventry 1, irq // IRQ EL1h kernel_ventry 1, fiq_invalid // FIQ EL1h kernel_ventry 1, error_invalid // Error EL1h (3) kernel_ventry 0, sync // Synchronous 64-bit EL0 kernel_ventry 0, irq // IRQ 64-bit EL0 kernel_ventry 0, fiq_invalid // FIQ 64-bit EL0 kernel_ventry 0, error_invalid // Error 64-bit EL0 (4) #ifdef CONFIG_COMPAT kernel_ventry 0, sync_compat, 32 // Synchronous 32-bit EL0 kernel_ventry 0, irq_compat, 32 // IRQ 32-bit EL0 kernel_ventry 0, fiq_invalid_compat, 32 // FIQ 32-bit EL0 kernel_ventry 0, error_invalid_compat, 32 // Error 32-bit EL0 #else kernel_ventry 0, sync_invalid, 32 // Synchronous 32-bit EL0 kernel_ventry 0, irq_invalid, 32 // IRQ 32-bit EL0 kernel_ventry 0, fiq_invalid, 32 // FIQ 32-bit EL0 kernel_ventry 0, error_invalid, 32 // Error 32-bit EL0 #endif END(vectors)
VBAR_EL1 register值在如下地方被赋值,此register是存储的vector table base address。
发生exception时,根据异常类型,得到在vector table里的offset,再加上VBAR_EL1的值即确定此exception处理入口
head.S
__primary_switched: adrp x4, init_thread_union add sp, x4, #THREAD_SIZE adr_l x5, init_task msr sp_el0, x5 // Save thread_info adr_l x8, vectors // load VBAR_EL1 with virtual msr vbar_el1, x8 // vector table address isb
原文:https://www.cnblogs.com/aspirs/p/14727921.html