基于Linux-3.9.4的mykernel实验环境的极简内核分析

382 + 原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/

一、实验环境

  win10 -> VMware -> Ubuntu16.04 -> QEMU -> linux-3.9.4

二、实验目的

  1、了解在一个极简内核中,为了实现多进程的切换,需要哪些必要的数据结构;

  2、了解对于一个OS来说,进程是如何启动以及如何基于时间片轮转对进程进行切换。

三、实验结果

  

图 1 实验结果 

四、代码分析

  (1) 对应的PCB(进程控制块)

   为了能够实现进程的切换和正常运行,对于每一个进程,都需要有一些必要的资源、参数。比如,对应进程的唯一标识(pid)、进程的状态(state)、每一个进程对应的堆栈(stack)、进程的入口地址(entry)、指向进程队列中位于当前进程的下一进程指针(pnext)等等。

                                                            

图 2 PCB结构体定义

                                                       

图 3 进程切换的大致流程图

  (2)进程切换的逻辑分析

  具体来讲,对于进程的上下文切换,需要在平常的C代码之间嵌入一些必要的汇编代码,以保存将要被替换的进程的相关信息(现场)以及执行下一的进程,对于新的进程,也并非是从头开始执行(第一次执行除外),而是从上一次被中断的地方继续开始执行。

                            

图 4 进程切换中实现进程间上下文切换的汇编代码

  (3)极简内核的整体流程分析

            

                    

图 5 极简内核整体运行流程图

  在个人看来,该极简内核的运行在本质上是一个死循环,在这个死循环中,基于固定时间片轮转思想,修改进程切换标志,在该死循环中查询进程切换标志,如果符合要求,则进行进程的切换,否则继续执行当前进程,不进行进程切换。当然,这个死循环,是由内核中的0号进程触发。0号进程是内核启动起来,经过相应的初始化之后,执行的第一个进程。

                                      

图 6 my_start_kernel中对0号进程的初始化

      ·          

  图 7 my_start_kernel中对进程链表的初始化(包括PCB初始化)

                    

图 8 my_start_kernel中执行的第一个进程(0号进程)

                          

图 9 时间片的实现(系统时钟中断      

 

图 10 0号进程死循环查询是否执行进程切换

四、总结

  通过分析实验代码,比较清楚地了解一个简单的时间片轮转多道操作系统内核,了解了操作系统的中断上下文和进程上下文切换。对于当前执行的进程来说,如果被分配到的时间片执行完,CPU 则会进行相应的进程切换。其中的调度程序,就是在维护一个就绪进程队列,当进程用完属于它的时间片后,在队列中就会按照优先级重新排序。这种调度方式,应该是属于一种比较简单、公平同时也是比较高效的方式。

原文地址:https://www.cnblogs.com/wyt123/p/10513256.html