零、源码及详细注释
.macro kernel_ventry, el, label, regsize = 64
sub sp, sp, #S_FRAME_SIZE //在堆栈中预留出S_FRAME_SIZE大小的空间
.macro kernel_entry, el, regsize = 64
.if \regsize == 32
mov w0, w0 // zero upper 32 bits of x0
.endif
stp x0, x1, [sp, #16 * 0] //入栈
stp x2, x3, [sp, #16 * 1]
stp x4, x5, [sp, #16 * 2]
stp x6, x7, [sp, #16 * 3]
stp x8, x9, [sp, #16 * 4]
stp x10, x11, [sp, #16 * 5]
stp x12, x13, [sp, #16 * 6]
stp x14, x15, [sp, #16 * 7]
stp x16, x17, [sp, #16 * 8]
stp x18, x19, [sp, #16 * 9]
stp x20, x21, [sp, #16 * 10]
stp x22, x23, [sp, #16 * 11]
stp x24, x25, [sp, #16 * 12]
stp x26, x27, [sp, #16 * 13]
stp x28, x29, [sp, #16 * 14]
.if \el == 0 // 异常等级0
clear_gp_regs // 清空寄存器
mrs x21, sp_el0 // x21 = sp_el0 如果异常发生在用户态(EL0)则pt_regs将保存用户态堆栈指针sp_el0 */
ldr_this_cpu tsk, __entry_task, x20 // 设置tsk为当前进程的task_struct, x20 = tpidr_el1/tpidr_el2
ldr x19, [tsk, #TSK_TI_FLAGS] // x19 = tsk->thread_info.flags
disable_step_tsk x19, x20 // 关闭mdscr_el1寄存器的SS位
apply_ssbd 1, x22, x23
.else //异常等级不为0
add x21, sp, #S_FRAME_SIZE //X21保存压入pt_regs数据之前的栈地址(栈框的位置) S_FRAME_SIZE:栈帧的大小
get_thread_info tsk //tsk = sp_el0
/* Save the task's original addr_limit and set USER_DS */
ldr x20, [tsk, #TSK_TI_ADDR_LIMIT] //x20 = tsk->thread_info.addr_limit
str x20, [sp, #S_ORIG_ADDR_LIMIT] //pt_regs->orig_addr_limit = x20
mov x20, #USER_DS //X2O = USER_DS = 1<<48
str x20, [tsk, #TSK_TI_ADDR_LIMIT] //tsk->thread_info.addr_limit