zoukankan      html  css  js  c++  java
  • Linux0.11内核源码——内核态进程切换的改进

    本来想自己写的,但是发现了一篇十分优秀的博客

    https://www.cnblogs.com/tradoff/p/5734582.html

    system_call的源码解析:https://blog.csdn.net/tq02h2a/article/details/2934094?utm_source=blogxgwz3 了解调用进程的流程

    理一理思路

    通过内核栈来切换进程的流程

      用户态fork触发int80中断 

        进入_system_call

          1.一些通用寄存器入栈保存(ds,es,fs)

          2.call  _sys_fork

            进入sys_fork

              1.通用寄存器压栈(gs,esi,edi,edx)

              2. copy_process建立一个新的进程,同时把返回值交给eax

          3.eax压栈,这个eax要交给res,父进程的eax(子进程pid)在父进程栈里,而子进程的eax(0)在子进程栈里。后面要修改eax的值了

          4.父进程被阻塞时执行reschedule:先把ret_from_sys_call压栈,然后call _schedule

             进入schedule

               1.时间片切换给新建的子进程

               2.switch_to

                 进入switch_to

                   1.保存当前进程栈帧

                   2.各种通用寄存器压栈  

                   3.切换pcb,重写TSS(重定位tss),切换内核栈,切换LDT

                   4.通用寄存器恢复,要格外注意这里,pop出来的所有寄存器都是应该从子进程内核栈里弹出来的,所以在copy_process时,栈顶应该有这几个对应的通用寄存器

                   到此为止已经进入子进程啦!

           下面就是ret_from_sys_call:

           5.通用寄存器恢复,和switch_to的第4步一样,这里恢复的通用寄存器也是子进程内核里探出来的,所以copy_process时,栈里要有对应的通用寄存器

           6.著名的iret实现从内核到用户的返回,同时res=eax

             1.如果是子进程返回,那么被压在内核栈里的eax=0

             2.如果是父进程返回,那么被压在内核栈里的eax=子进程pid  

    到此为止,fork调用结束啦!

     最后贴一张大神画的内核栈图

  • 相关阅读:
    python生成四位随机数
    解决mysql远程连接失败的问题
    python中的sort、sorted排序
    rest_framework之status HTTP状态码
    vim的卸载以及环境的配置小记
    vue项目如何引用jquery
    VSCode 安装Vue 插件
    Element-UI tree 组件 点击后高亮显示的样式修改(背景色)
    webstorm安装vue插件及安装过程出现的问题
    Vue el-date-picker 日期组件的使用
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12038747.html
Copyright © 2011-2022 走看看