mips 异常处理和进程切换
一. 内核栈 每个进程拥有一个内核栈,调度切换至一个新进程时,会根据 task_struct->stack(struct thread_info 结构体类型) 的值设置 *kernelsp (当前正在运行进程之内核栈栈顶),将 kernelsp 的值设置为 task_struct->stack + THREAD_SIZE - 32 ( MIPS 下,使用 set_saved_sp 宏来完成设置)。 内核栈主要用于进程运行时产生异常,将异常的现场保存在内核栈上(使用 SAVE_ALL 宏, SAVE_ALL 宏包括 SAVE_SOME 宏)。 二. 异常产生时现场的保存 使用 SAVE_SOME 保存上下文时,如发现从用户态切入核心态,则首先用 get_saved_sp 宏将 *kernelsp 置入 sp ,也就是说: 若是用户态 --> 内核态,则 k0 = sp, sp = *kernelsp - PT_SIZE , store k0, PT_R29(sp) ,保存其它寄存器。 若是内核态 --> 内核态,直接 k0 = sp, sp = sp - PT_SIZE , store k0, PT_R29(sp) ,然后保存其它寄存器。 本质是内核栈上分配 PT_SIZE ( =sizeof(struct pt_regs) )大小的空间,作为上下文的保存空间。保存时所有数据精心组织,最后就是一个 struct pt_regs 结构。 三. 进程的切换过程 进程 A --> 时钟中断 --> schedule --> switch_to(resume) --> schedule 返回 --> ret_from_irq --> 进程 B 1 、时钟中断后使用 SAVE_ALL 在内核栈上保存 $0, $2, $3,...