sunsetyang
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2007-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1713回复:0

linux/i386 switch_to [forwarded from USTC bbs]

楼主#
更多 发布于:2002-01-30 02:10
发信人:Free_Os (【9611】???)  版面名称:Kernel(1643)
标 题:linux/i386 switch_to
发信站:中国科大BBS站 (Thu, 06 Dec 2001 22:25:55 )
标 记:标记
* preface
  yes, it may be an old topic; but it does take me a long time to
understand the whole thing.
  and, if i am talking something you have known before, forgive me;
but please make sure you are not missing something :-)
  here we go!

*
  macro switch_to(prev,next) perform the machine-depend low-level codes for
 context switching if task scheduling needed; as convetion, switch_to()
 is defined in $/arch/asm-xx/system.
  generaly, switch_to(prev,next) do things following:
   * save context to current kernel stack(\"prev\")
   * switch kernel stack to \"next\"
   * load context into kernel stack from \"next\"
   
  so that, when switch_to returns, kernel is running on new
 process context(\"next\") ;
   Let\'s go through switch_to for i386;

   $/include/asm-i386/system.h
    ...
     01 #define switch_to(prev,next,last) do {
     02 asm volatile(\"pushl %%esi\\n\\t\"
     03        \"pushl %%edi\\n\\t\"
     04        \"pushl %%ebp\\n\\t\"
     05        \"movl %%esp,%0\\n\\t\"    /* save ESP */
     06        \"movl %3,%%esp\\n\\t\"    /* restore ESP */
     07        \"movl $1f,%1\\n\\t\"     /* save EIP */
     08        \"pushl %4\\n\\t\"       /* restore EIP */
     09        \"jmp __switch_to\\n\"
     10        \"1:\\t\"
     11        \"popl %%ebp\\n\\t\"
     12        \"popl %%edi\\n\\t\"
     13        \"popl %%esi\\n\\t\"
     14        :\"=m\" (prev->thread.esp),\"=m\" (prev->thread.eip),
     15        \"=b\" (last)
     16        :\"m\" (next->thread.esp),\"m\" (next->thread.eip),
     17        \"a\" (prev), \"d\" (next),
     18        \"b\" (prev));
     19 } while (0)
  ... 
  03-04:
   save edi,ebp on _current_ kernel stack
  05:
   save esp to prev->thread.esp; ready to switch kernel stack.
  06:
   load esp from next->thread.esp; kernel stack switching done; following
  code runs on stack of \"next\";
  07:
   save eip to prev->thread.eip; when \"prev\" gets schedued next time, i
  it will start from L.10,\"1:...\";
  08:
   push next->thread.eip on stack; and when __switch_to returns, IP pops
  from stack: that\'s next->thread.eip; please note,
    * _jmp_ to \"__switch_to\", not call; return ip is \"pushed\",
     not \"call\"
    * pass parameter to \"__switch_to\" via registers, not stack;
     for more details, see FAST_CALL;
    * task_struct{}->thread.eip for newly \"fork\"ed process, is
     \"ret_from_fork\",copy_thread() in $/arch/i386/kernel/process.c;
     so when process gets scheduled first time, it starts from
     \"ret_from_fork\"; but by the second time, it will be \"1:...\";
    * when process is \"execv\"ed, task_struct{}->thread.eip is not changed;
     but \"pt_regs->eip = new_ip\",$/include/asm-i386/processor.h,
     start_thread;
    * 
  idle process(PID=0)  kernel thread(\"init\")   \"init\" task (PID=1)
   created staticly    fork            execv 
   n/a          ret_from_fork/L.10\"...\"=>L.10\"...\",inherited
   n/a          static void init()    elf entry(exe or intrp)
    
  Note:
   n/a : i don\'t know what it\'s, and i don\'t care
   row1: how it is borned?
   row2: thread.eip, for \"switch_to\"
   row3: pt_regs->eip, for \"iret\" ;
    
   * =>$/kernel/fork.c
     sys_fork -> do_fork() //arch-independent, but pt_regs{} is
     arch-dependent, and so do copy_thread, copy_mm, copy_...
    =>$/arch/xx/process.c
     ->copy_thread(), arch-dependent process context setting up;
     ->copy_...

* Summary
 [n/a]

--
※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]


[color=red]Optimization[/color] In Progress . . . Welcome to http://mail.ustc.edu.cn/~chyang/
游客

返回顶部