Linux2.6进程切换

1.进程切换是指:保存prev进程的上下文,用next的上下文替代。

其中上下文包括:页全局目录、内核态堆栈、硬件上下文。


2.80x86为进程切换提供的硬件支持:

第一种:通过任务门

第二种:通过JMP和CALL指令:把硬件上下文存在TSS中,执行这条指令时,通过硬件自动切换TSS,完成硬件上下文的过程

TSS是任务状态段,只能存放在GDT中,不能存放在LDT中


3.Linux使用的硬件上下文切换方法:

通过一组MOV指令逐步执行切换,手动模拟1的过程

因为这样效率较高,也便于各种检查和保护


4.Linux的进程切换不使用80x86提供的硬件方法,但是为了与80x86兼容,仍会为每个CPU创建一个TSS(按照80X86,应该是为每个进程创建一个),供当前运行的进程使用。

每当切换进程时,更新TSS中的内容(按照80X86,应该是切换TSS)


5.内核堆栈与硬件上下文的切换是由宏switch_to()完全的,这段程序短小精悍,很重要。可惜汇编没学好

(1)把prev和next的值分别保存到EAX和EDX中

(2)把EFLAGS和EBP的内容保存到prev内核栈中

(3)ESP的内容保存到prev->thread.esp中

(4)next->thread.esp的内容装入ESP中//从现在开始,当前堆栈是next的内核堆栈

(5)把标记为1的地址存入prev->thread.eip

(7)把next->thread.eip的值压入next的内核堆栈//这个值往往是标记为1的地址,这是最后入栈的,因此从下面的一个调用返回后,会执行标记为1的程序

(8)__switch_to():主要是针对TSS的操作,见6

(9)标号为1的指令:弹出EFLAGS和EBP

(10)将EAX的内容拷贝到last标识的区域中

switch_to(prev, next, last)

这个函数有三个参数,

第一个参数和第二参数都是输入参数,分别表示被替换的进程和新的进程的位置。

第三个参数是输出参数,记录被替换的进程被替换到的位置,见程序中的EAX


6.__switch_to()

(1)有选择地保存prev_p的FPU、MMX、XMM等寄存器

(2)把next_p->thread.esp0装入TSS的esp0中

(3)把next_p进程使用的线程局部存储段装入本地CPU的GDT

(4)加载next进程的fs段和gs段

(5)更新TSS的I/O位图

(6)ret,返回到栈中标号为1的指令

原文地址:https://www.cnblogs.com/windmissing/p/2559814.html