定义
每个进程都有用户堆栈和内核堆栈两个堆栈。进程在用户态时使用用户堆栈,陷入到内核态时便使用内核堆栈。
切换过程
- 用户进程X正常运行时,堆栈寄存器ESP指向的的用户堆栈地址。
- 当进程X调用某系统调用时(int 0x80),CPU会首先将用户堆栈地址保存到内核堆栈内(还有EIP,FLAG等寄存器),然后将ESP指针指向内核堆栈地址(还有将内态的EIP,FLAG等也一并存入相应的寄存器中,切换到用户态进程),这时便切换到来内核堆栈中。
- 当系统调用完成后,再将用户堆栈地址从内核堆栈中出栈存储ESP寄存器中,此时便切换到了用户堆栈。
中断过程
- X函数调用syscall_x (用户态)
- int 0x80 (保存部分寄存器,内核态)
- syscall_call (SAVE_ALL保存全部现场,内核态)
- iret后(用户态)
中断代码(简易)
ENTRY(system_call)
RING0_INT_FRAME
ASM_CLAC
push_cfi %eax #保存系统调用号
SAVE_ALL #保存现场⚠️
GET_THREAD_INFO(%ebp)
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%epb)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax #检查传入到系统调用号是否合法
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eas,4) #执行相应的系统调用函数
movl %eax,PT_EAX(%ebp) #保存结果到eax寄存器
syscall_exit:
testl $_TIF_ALLWORK_MASK,%ecx #检查是否有其他任务处理
jne syscall_exit_work #进行进程调度
restore_all
TRACE_IRQS_IRET #恢复现场
irq_return:
INTERRUPT_RETURN #iret 将ESP,EIP,FLAG等寄存器恢复为用户态
网友评论