如何实现内核级进程切换
在这篇文章中,我们在父进程上通过fork()函数创建一个子进程一窥内核级进程切换的来龙去脉。
1.通过中断函数从用户栈进入内核栈:
在用户级线程内调用系统函数fork(),fork()函数体如下:
fork:
mov %eax,__NR_fork
INT 0x80
mov res,%eax
int 0x80指令详解:int 0x80为中断指令,会将内核栈和用户栈关联(通过SS:SP),并且将当前用户级线程的指令位置记录在CS:PC中。该指令会调用中断处理函数_system_call()。
2.线程之间的切换
线程切换任务主要是在_sys_call()函数内执行,即在该过程中只有一个_sys_call函数,但进函数的线程和出函数的线程并不相同。system_call()会将当前用户级线程的一些寄存器压栈进行记录,并调用_system_fork()函数来创建一个新进程。其函数体如下:
_system_call:
push %ds..%fs ;用户态寄存器压栈记录
pushl %edx...
call sys_fork ;该函数才是执行线程切换功能的函数
pushl %eax
movl _current,%eax
cmpl $0,state(%eax) ;判断当前进程是否阻塞,非零为阻塞