为了保证kernel_exit时能恢复准确的现场,这里有必要对第一现场先做保存。 其次设置栈帧大小S_FRAM_SIZE,S_FRAM_SIZE根据pt_regs结构体大小而设定。 pt_regs结构体: 另外就是读取elr_el1和spsr_el1等寄存器值。总之,kernel_entry主要将CPU寄存器按照pt_regs结构体的定义将异常第一现场保存到栈上。 (2)判断异常...
为了保证kernel_exit时能恢复准确的现场,这里有必要对第一现场先做保存。 其次设置栈帧大小S_FRAM_SIZE,S_FRAM_SIZE根据pt_regs结构体大小而设定。 pt_regs结构体: 另外就是读取elr_el1和spsr_el1等寄存器值。总之,kernel_entry主要将CPU寄存器按照pt_regs结构体的定义将异常第一现场保存到栈上。 (2)判断异常...
为了保证kernel_exit时能恢复准确的现场,这里有必要对第一现场先做保存。 其次设置栈帧大小S_FRAM_SIZE,S_FRAM_SIZE根据pt_regs结构体大小而设定。 pt_regs结构体: 另外就是读取elr_el1和spsr_el1等寄存器值。总之,kernel_entry主要将CPU寄存器按照pt_regs结构体的定义将异常第一现场保存到栈上。 (2)判断异常...
为了保证kernel_exit时能恢复准确的现场,这里有必要对第一现场先做保存。 其次设置栈帧大小S_FRAM_SIZE,S_FRAM_SIZE根据pt_regs结构体大小而设定。 pt_regs结构体: 另外就是读取elr_el1和spsr_el1等寄存器值。总之,kernel_entry主要将CPU寄存器按照pt_regs结构体的定义将异常第一现场保存到栈上。 (2)判断异常...
.macro kernel_exit /* 从pt_regs->pc中恢复elr_el1, 从pt_regs->pstate中恢复spsr_el1 */ ldp x21, x22, [sp, #S_PC] // load ELR, SPSR msr elr_el1, x21 // set up the return data msr spsr_el1, x22 ldp x0, x1, [sp, #16 * 0] ldp x2, x3, [sp, #16 * 1] ldp ...
.macro kernel_exit/* 从pt_regs->pc中恢复elr_el1,从pt_regs->pstate中恢复spsr_el1*/ldp x21, x22, [sp, #S_PC] // load ELR, SPSRmsr elr_el1, x21 // set up the return datamsr spsr_el1, x22ldp x0, x1, [sp, #16 * 0]ldp x2, x3, [sp, #16 * 1]ldp x4, x5, [sp...
所以此处的意图是通过更改pt_regs.pc来更改ELR中的内容,并在exception return时跳到ELR指定的地址,对应了单步调试状态机中 "Programs the ELR_ELx ..." 这一步。 但对于单步调试来说,一般情况下并不会改写PC。 接下来来到函数的第二部分,即调用kernel_enable_single_step() 来使能单步调试。
保存通用寄存器x0~x29到栈框里pt_regs->x0~x29 */ stpx0,x1, [sp,#16*0] stpx2,x3, [sp,#16*1] stpx4,x5, [sp,#16*2] stpx6,x7, [sp,#16*3] stpx8,x9, [sp,#16*4] stpx10,x11, [sp,#16*5] stpx12,x13, [sp,#16*6] ...
在task_pt_regs(current)->stackframe创建一个最终帧记录,这样unwinder就可以根据任务堆栈中的位置来识别任何任务的最终帧记录。保留整个pt_regs空间使用户任务和kthread保持一致性。 /* * Initialize CPU registers with task-specific and cpu-specific context. ...
所以此处的意图是通过更改pt_regs.pc来更改ELR中的内容,并在exception return时跳到ELR指定的地址,对应了单步调试状态机中 "Programs the ELR_ELx ..." 这一步。 但对于单步调试来说,一般情况下并不会改写PC。 接下来来到函数的第二部分,即调用kernel_enable_single_step() 来使能单步调试。