linux内核进程切换代码分析(图不错)

转载 2011年01月06日 10:01:00

#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内核进程切换  本文主要参考了Understanding The LinuxKernel 和水木精华区的分析进程切换宏 switch_to 。感谢相关的作者!本文中有部分内容直接从上面提到...
  • xiaoxiaomuyu2010
  • xiaoxiaomuyu2010
  • 2013年09月23日 16:04
  • 5492

linux内核进程切换代码分析

#define switch_to(prev,next,last) do{       asm volatile {"pushl %%esi/n/t"                         ...
  • ywf861029
  • ywf861029
  • 2011年01月05日 09:43
  • 1983

Linux内核的进程切换(上)

硬件上下文概念尽管每个进程都可以拥有属于自己的地址空间,但所有进程必须共享CPU寄存器。因此在,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。而这些必须装入的寄存器中的数据就称为...
  • GetNextWindow
  • GetNextWindow
  • 2015年08月19日 11:30
  • 1049

《Linux内核分析》(二)——从一个简单Linux内核分析进程切换原理

作者:徐恒 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 实验环境:c+Lin...
  • FIELDOFFIER
  • FIELDOFFIER
  • 2015年03月15日 22:37
  • 912

linux内核分析:进程切换机制

“陈涛 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”这次作业主要运行一个小程序...
  • u010856103
  • u010856103
  • 2017年03月05日 17:55
  • 262

Linux内核进程切换

Linux内核进程切换     本文主要参考了Understanding The Linux Kernel 和水木精华区的分析进程切换宏 switch_to 。感谢相关的作者!本文中有部分内容直...
  • cogbee
  • cogbee
  • 2013年10月25日 16:26
  • 591

Linux arm 进程切换

Linux arm 进程切换 Linux进程切换的函数是在函数schedule()中实现的,其中主要的函数是: schedule(void) { …… context_switch(rq, ...
  • lieye_leaves
  • lieye_leaves
  • 2014年06月12日 20:59
  • 1359

进程切换的代码分析

  • titer1
  • titer1
  • 2010年03月12日 20:06
  • 549

linux内核之进程切换

进程切换       前面所介绍的schedule()中调用了switch_to宏,这个宏实现了进程之间的真正切换,其代码存放于include/ i386/system.h: 1   #defin...
  • conjimmy
  • conjimmy
  • 2011年12月16日 11:45
  • 346

一张图看尽 Linux 内核运行原理

  • testcs_dn
  • testcs_dn
  • 2016年01月06日 13:03
  • 2853
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux内核进程切换代码分析(图不错)
举报原因:
原因补充:

(最多只允许输入30个字)