linux内核进程切换代码分析(图不错)
2011-01-06 10:01
225 查看
#define switch_to(prev,next,last)
do{
asm volatile {"pushl %%esi/n/t"
"pushl %%edi/n/t"
"movl %%esp,%0/n/t"
"movl %3,%%esp/n/t"
"movl $1f,%1/n/t"
"pushl %4/n/t"
"1/t"
"popl %%ebp/n/t"
"popl %%edi/n/t"
"popl %%esi/n/t"
:"m=" (prev->thread.esp),"m" (prev->thread.eip), /
"b"(last)
:"m" (next->thread.esp),"m" (next->thread.eip),
"a"(prev), "d"(next),
"b"(prev));
}while(0)
其中%0和%1都在内存中,分别为prev->thread.esp和
prev->thread.eip,而%2则与寄存器EBX结合,对应于参数中的last。其中%3和%4在内存中,分别为
next->thread.esp和next->thread.eip,%5、%6和%7分别与寄存器EAX、EDX和EBX结合,分别对应
于prev,next,prev.
如图所示,A为此时正运行的进程(prev),B为待切换的进程(next)。切换过程一共分为四步:
第一步:即movl %%esp,%0也就是将寄存器esp中的值保存在进程A的thread.esp中。
第二步:即movl %3,%%esp也就是将进程B的thread.esp的值赋给寄存器esp。(实际上这个值就
是上一次从B中切换走的时候执行的第一步的结果。为了要返回,必须为以后考虑周全。)
第三步:即movl $1f,%1其中1f就是说程序后面标号为1的地方,将标号为1的地方的代码的地址保存
到A的thread.eip中。
第四步:即pushl %4,将进程B的thread.eip的值压栈,此时的esp指向已是进程B的堆栈。(实际上此时的thread.eip就是上一次从B中切换走的时候第三步执行的结果,即标号一得位置。所以任何进程恢复运行,首先肯定是执行的标号1的代码。)
这里要说明的是,pushl %4后面的一句代码是调转jmp __switch_to 而__switch_to是个函数,他执行完成以后会有一个ret的操作,即将栈中的第一个地址作为函数返回的地址,所以就会跳到标号1的地方去执行代码了。
由于__switch_to的代码在schedule()中,而shedule()函数又在其他系统调用函数中,比如sys_exit()中,所以先返回
到调用B进程上次切换走时的schedule()中,然后返回到调用schedule()的系统调用函数中,最后系统调用又是在用户空间调用的,所有返回
到系统调用的那个地方,接着执行用户空间的代码。这样就彻底的回到了B进程。注意由于此时的返回路径是根据B堆栈中保存的返回地址来返回的,所以肯定会返
回到B进程中。
相关文章推荐
- linux内核进程切换代码分析
- Linux内核中的GPIO系统之(3):pin controller driver代码分析
- 云课堂 Linux内核分析 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- Linux内核分析--理解进程调度时机、跟踪分析进程调度和进程切换的过程
- linux内核TCP拥塞控制两个速率增长阶段代码分析
- Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程
- Linux内核分析8:理解进程调度时机、进程调度、进程切换
- Linux内核中的GPIO系统之(3):pin controller driver代码分析
- 详细分析contrex-A9的汇编代码__switch_to(进程切换)
- linux内核分析---系统调用实现代码分析
- Linux内核分析:理解进程调度时机跟踪分析进程调度与进程切换的过程
- Linux内核分析2:一个简单的时间片轮转多道程序内核代码分析
- Linux内核分析(八):Linux进程调度的时机和进程切换
- linux内核分析第四周-使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- Linux进程切换代码分析
- 第4节 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用【Linux内核分析】
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
- Linux内核2.6.14源码分析-双向循环链表代码分析(巨详细)
- Linux内核分析,c程序汇编代码分析--第一周