《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

时间:2021-01-04 03:09:23

进程的切换和系统的一般执行过程

一、进程调度的三个时机:

1.中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();

2.内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度;

3.用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。

二、switch_to完成寄存器的切换

switch_to(prev,next,prev);

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

进程切换:为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换(process switch)、

任务切换(task switch)或上下文切换(context switch)。

schedule()函数选择一个新的进程来运行,调用switch_to来进行关键上下文切换。

switch_to完成寄存器的切换:先保存当前进程的寄存器,再进行堆栈切换,自此后所有的压栈都是在新进程的堆栈中了,再切换eip,这样当前进程

可以从新进程中恢复,还有其他必要的切换。

进程上下文包含了进程执行需要的所有信息,包括:

1、用户地址空间:包括程序代码,数据,用户堆栈等

2、控制信息:进程描述符,内核堆栈等

3、硬件上下文(与中断保存硬件上下文的方法不同)

三、Linux系统的一般执行过程(最一般的情况)

正在运行的用户态进程X切换到运行用户态进程Y的过程

正在运行的用户态进程X

发生中断——

save cs:eip/esp/eflags(current) to kernel stack;

then load cs:eip(系统调用的起点,entry of a specific ISR) and ss:esp(point to kernel stack)

进入内核代码,SAVE_ALL //保存现场

(这一步也可能不发生)中断处理过程中或中断返回前调用了schedule(),其中的switch_to做了关键的进程上下文切换

标号1之后开始运行上一步中选中的用户态进程Y(这里Y曾经通过以上步骤被切换出去过因此可以从标号1继续执行)

restore_all //恢复现场

iret - pop cs:eip/ss:esp/eflags from kernel stack

继续运行用户态进程Y

四、实验:

1.下载menu系统:

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

2.启动gdb进行调试:

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

3.在schedule处设置断点,点击c运行:

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

4.停在断点1:schedule

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

5.停在断点2:context_switch

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

6.按n单步执行:

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

五、总结:

Linux系统的一般执行过程:参见三。