您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > linux_进程切换核心代码switch_to剖析
PA15/13/20131ConfidentialLinux内核剖析之进程切换郭海林2012.10.20王荣帅修改版(2013.5.14)PA15/13/20132ConfidentialAT&T汇编基础•AT&T汇编与Intel汇编比较•GCC内联汇编PA15/13/20133Confidential进程切换概述•__schedule()•prev=rq-curr;•next=pick_next_task(rq);•if(likely(prev!=next))context_switch(rq,prev,next);•执行进程的切换:–切换页全局目录以安装一个新的地址空间–切换内核态堆栈和硬件上下文PA15/13/20134Confidential进程切换概述•硬件上下文——共享的CPU寄存器•进程切换时,硬件上下文保存在:–task_struct的类型为thread_struct的thread字段•大部分寄存器,如esp,eip...–内核态堆栈•状态寄存器、通用寄存器,如eax,ebx...PA15/13/20135Confidentialswitch_to宏1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:9.popl%%ebp10.popfl/*outputparameters*/:[prev_sp]=m(prev-thread.sp),[prev_ip]=m(prev-thread.ip),=a(last)/*inputparameters:*/:[next_sp]m(next-thread.sp),[next_ip]m(next-thread.ip),[prev]a(prev),[next]d(next)switch_to(prev,next,last)PA15/13/20136Confidential切换过程ABt_st_s内核栈内核栈thread_infothread_info1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]RegisterT_S即Thread_structT_S即Thread_structthread;(task_struct-thread_struct)PA15/13/20137Confidential切换过程ABt_st_s内核栈内核栈thread_infothread_info1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]flagsRegisterPA15/13/20138Confidential切换过程ABt_st_s内核栈内核栈thread_infothread_info1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]flagsebpRegisterPA15/13/20139Confidential切换过程A(prev)B(next)t_st_s内核栈内核栈thread_infothread_info1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]flagsebpthreadespRegisterPA15/13/201310Confidential切换过程A(prev)B(next)t_st_s内核栈内核栈thread_infothread_info2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]flagsebpebpthreadspflagsthreadsp完成内核栈的切换!是不是就完成了进程的切换呢?RegisterPA15/13/201311Confidential切换过程A(prev)B(next)t_st_s内核栈内核栈thread_infothread_info4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:flagsebpebpthreadspflagsthreadspipRegisterPA15/13/201312Confidential切换过程A(prev)B(next)t_st_s内核栈内核栈thread_infothread_info4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:flagsebpebpthreadspflagsthreadspip4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:eipipRegisterPA15/13/201313Confidential切换过程A(prev)B(next)t_st_s内核栈内核栈thread_infothread_info4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:flagsebpebpthreadspflagsthreadspip6.pushl%[next_ip]7.jmp__switch_to8.1:9.popl%%ebp10.popfleip__switch_to是一个函数!ipreturn时,将jump之前压入栈中的元素eip赋值给eip!RegisterPA15/13/201314ConfidentialPA15/13/201315Confidentialswitch_to(prev,next,last)•last干嘛的?•如果是switch_to(prev,next):1:进程Aprev=Anext=B1:进程Bprev=Bnext=other......1:进程Cprev=Cnext=Aswitch_to(A,B)switch_to(C,A)进程A恢复切换出去之前的上下文,但此时无法知道自身是由哪个进程切换来的!PA15/13/201316Confidentialswitch_to宏1.pushfl2.pushl%%ebp3.movl%%esp,%[prev_sp]4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:9.popl%%ebp10.popfl/*outputparameters*/:[prev_sp]=m(prev-thread.sp),[prev_ip]=m(prev-thread.ip),=a(last),/*inputparameters:*/:[next_sp]m(next-thread.sp),[next_ip]m(next-thread.ip),[prev]a(prev),[next]d(next)switch_to(prev,next,last)PA15/13/201317Confidentialswitch_to(prev,next,last)•A需要在切换之后保存对C的引用!•switch_to(prev,next,prev)=a(last)......switch_to(C,A,C)switch_to(A,B,A)1:进程Aprev=Anext=Beax=A1:进程Bprev=Bnext=othereax=Blastprev=Aeax=A1:进程Cprev=Cnext=Aeax=Ceax=Clastprev=CPA15/13/201318Confidential切换到新建进程A(prev)B(next)-newt_st_s内核栈内核栈thread_infothread_info4.movl%[next_sp],%%esp5.movl$1f,%[prev_ip]6.pushl%[next_ip]7.jmp__switch_to8.1:flagsebpebpthreadspflagsthreadspip6.pushl%[next_ip]7.jmp__switch_to8.1:9.popl%%ebp10.popfleipipret_from_forkRegister
本文标题:linux_进程切换核心代码switch_to剖析
链接地址:https://www.777doc.com/doc-3372461 .html