仔细揣摩了一段时间.
系统调用过程,用户进程进入内核态,进程栈进入内核态栈, cpu进入内核态,cpu用户态各寄存器的值保存到内核态栈,执行内核态代码. 执行完从内核态返回到用户态,包括进程栈返回到用户态栈,cpu返回到用户态,cpu各寄存器的值用之前保存在内核态栈的值还原. 内核在执行系统调用时处于进程上下文中,current指针指向当前进程,即引发系统调用的进程。
1 系统调用的过程中 可以发生进程切换(1 来自时钟中断,时间片用完,schedule()。2内核态代码执行过程中阻塞,主动schedule() )。2 系统调用的过程中 可以发生中断,中断任意时刻可以发生,中断不属于任何一个进程上下文.
a 当前进程是用户态 cpu进入内核态,使用栈进入到中断栈,并且在中断栈保存用户态各寄存器的值,执行中断代码,中断代码执行过程中 不能被阻塞, 不能被切换。执行完中断代码后,从中断栈恢复用户态寄存器值,cpu进入用户态。(用户态进入到内核栈时,该栈时空的,中断代码可以直接使用进程的内核态栈)
b 当前进程是内核态,使用栈进入到中断栈,并且在中断栈保存内核态各寄存器的值,执行中断代码,执行完中断代码后,从中断栈恢复内核态寄存器值.
c 中断代码执行时,处在中断上下文.不属于任何一个进程上下文.
d 每CPU变量中会有两个栈单独用于中断过程 分别用于软中断和硬中断 (2.6.x版本后)
3 从内核态返回到用户态的过程中,有很多事情都是这个环节里面做的.
a .检查 need_resched,当前进程是否需要发起schedule() ,这个过程也会发生进程切换
b 会检查所有进程是否有信号到达(深入理解linux内核 第三版 422页 ), 信号的处理是在这个过程来触发的。之前看了很多资料,都没发现一个可以进入信号处理的入口. 几乎所有的文章都是讲怎么发信号,怎么处理信号.就是没有一个说道有信号达到的进程是如何感知到,并且被调度.