阅读:1713回复:0
linux/i386 switch_to [forwarded from USTC bbs]
发信人: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] |
|
|