“平安的祝福 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

一、初始化进程

操作系统内核启动入口函数是void __init my_start_kernel(void);

在这里简单定义进程的的两个cpu状态:

struct Thread {
    unsigned long        ip; //表示eip指令
    unsigned long        sp;//表示esp,栈顶指针
};

在此函数中初始化第一个进程--pid=0;一切进程都是以它为父进程。

在初始化第一个进程时,分配进程pid=0,指定栈顶指针,初始化pcb的命令即ip的值--进程my_process的入口地址。

运行第一个进程的流程

设置进程状态为正在运行,通过嵌入式汇编程序使进程占据cpu运行

asm volatile(
        "movl %1,%%esp\n\t"     /* set task[pid].thread.sp to esp */
        "pushl %1\n\t"             /* push ebp */
        "pushl %0\n\t"             /* push task[pid].thread.ip */
        "ret\n\t"                 /* pop task[pid].thread.ip to eip */
        "popl %%ebp\n\t"
        :
        : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)    /* input c or d mean %ecx/%edx*/
    );

首先esp跳转到该进程的栈顶位置,将该进程ebp压入栈(由于第一个进程ebp==esp),将该进程的ip压入栈顶。然后将ret指令,可以修改eip的值,使得该进程获得cpu的指令权限。再弹出ebp,恢复栈底的位置。

二、进程的切换

本次小的时间片轮转的采用的是时钟中断的方法进行调度。在my_process的进程中,检测中断的标志,有的话,就进行进程切换。

进程切换分两种情况,一种是正在运行的进程切换,另一种是没有运行的进程切换

正在运行的进程切换

通过下面的一段嵌入式汇编实现切换,然后使下一个进程转换成正在运行的状态

asm volatile(    
            "pushl %%ebp\n\t"         /* save ebp */
            "movl %%esp,%0\n\t"     /* save esp */
            "movl %2,%%esp\n\t"     /* restore  esp */
            "movl $1f,%1\n\t"       /* save eip */    
            "pushl %3\n\t"
            "ret\n\t"                 /* restore  eip */
            "1:\t"                  /* next process start here */
            "popl %%ebp\n\t"
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        );

首先保存原来的ebp,esp,ip,通过将ebp压栈,进程cpu状态保存esp的值和ip的值。

接下来将esp跳转到要切换的栈顶,将其ip值压栈,然后ret指令使eip获得其cpu指令权,最后将ebp等于原来进程ebp的值。即栈底不变。

没有在cpu上运行的进程切换

首先转换进程的状态成正在运行,然后通过下面的一段嵌入式汇编实现切换

asm volatile(    
            "pushl %%ebp\n\t"         /* save ebp */
            "movl %%esp,%0\n\t"     /* save esp */
            "movl %2,%%esp\n\t"     /* restore  esp */
            "movl %2,%%ebp\n\t"     /* restore  ebp */
            "movl $1f,%1\n\t"       /* save eip */    
            "pushl %3\n\t"
            "ret\n\t"                 /* restore  eip */
            : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
            : "m" (next->thread.sp),"m" (next->thread.ip)
        );

首先保存原来的ebp,esp,ip,通过将ebp压栈,进程cpu状态保存esp的值和ip的值。

接下来将esp跳转到要切换的栈顶,ebp跳转到要切换的栈底,由于进程没有运行所以ebp=esp,将其ip值压栈,然后ret指令使eip获得其cpu指令权。

下面是内核编译完成的图片:

下面这张是进程在切换时的图片

三、总结

操作系统首先进入初始化启动内核,在启动内核时先完成第一个0号进程,然后根据需要不断创建进程。并根据一定的调度算法进行进程的切换。

Linux内核分析--操作系统是如何工作的的更多相关文章

  1. Linux内核分析——操作系统是如何工作的

    万子惠 + 原创作品转载请注明出处 + <Linux内核分析> 实验部分 使用实验楼的虚拟机打开shell 然后cd mykernel 您可以看到qemu窗口输出的内容的代码mymain. ...

  2. Linux内核分析— —操作系统是如何工作的(20135213林涵锦)

    mykernel实验指导(操作系统是如何工作的) 实验要求 运行并分析一个精简的操作系统内核,理解操作系统是如何工作的 使用实验楼的虚拟机打开shell cd LinuxKernel/linux-3. ...

  3. linux内核分析--操作系统是如何工作的?

    一个简单的时间片轮转多道程序 操作系统的"两把剑":中断上下文(保存现场和恢复现场)和进程上下文的切换 源代码的分析 *使用的源代码为视频中所使用的精简内核的源代码 首先分析myp ...

  4. 20135239益西拉姆 Linux内核分析 操作系统是怎样工作的?

    益西拉姆+ 原创作品+ <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 堆栈 堆栈是C语言程序运行时 ...

  5. LInux内核分析——计算机是如何工作的进行

    万子惠 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 " 实 ...

  6. linux内核分析--计算机是如何工作的

    实验部分 使用gcc -S -o main.s main.c -m32命令将源代码编译成汇编代码. 源代码如下: int g(int x) { return x + 9; } int f(int x) ...

  7. Linux内核分析— —计算机是如何工作的(20135213林涵锦)

    实验部分 (以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码, int g(i ...

  8. Linux内核分析——计算机是如何工作的

    马悦+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.计算机是如何工作的 ( ...

  9. Linux内核分析 计算机是如何工作的——by王玥

    1.冯诺依曼体系结构:也就是指存储程序计算机 硬件(存储程序计算机工作模式): 软件(程序员角度): 2.API:程序员与计算机的接口界面 ABI:程序与CPU的接口界面 3.X86的实现: 4.X8 ...

随机推荐

  1. C++实现VPN工具之代码示例

    创建.连接.挂断.删除VPN实现起来并不难,下面给出一套比较完整的代码.该段代码只是示例代码,但是已经通过了编译,对API的使用和VPN操作步骤是没问题的.具体每个API代表的意义可以参看<C+ ...

  2. Html5 postMessage

    解释: 跨文档消息传输Cross Document Messaging. 编写代码前注意判断浏览器是否支持Html5 实例: b页面向a页面发送消息. <!DOCTYPE> <htm ...

  3. redis 中文字符显示

    2015年5月20日 09:57:01 星期三 方法一: redis-cli -h --raw 方法二: linux 终端: echo -e "\xe7\xa5\x9e\xe6\xa3\x8 ...

  4. K3中添加的一条新数据,其在数据库中的位置

    最近研究将K3系统与生产管理系统结合起来,减少工作量,但如何确定其各自后台数据库的构成,其对应数据各自位于那张表内,总结了一下: 1.从百度搜索,查看表结构,然后找到目标表    另:K3数据库中单独 ...

  5. iOS-JavaScript向WKWebView传值

    一.本地代码所需操作 1.创建viewController并遵守协议 @interface ViewController ()<WKNavigationDelegate,WKScriptMess ...

  6. 由浅入深剖析.htaccess

    转自:http://blog.csdn.net/21aspnet/article/details/6908025 [-] htaccess文件使用前提 htaccess基本语法介绍 现学现用学习正则表 ...

  7. vs c# int & int32

    在vs c#中,int就等价于int32, 所以通常也是使用int32 当在统计总数时,最好使用int32,int16数值范围太小,如果超出,就会变成随机数.

  8. Xcode - 修改变量名、类名及字符串的替换操作

    在做iOS开发代码优化的工作时,优化代码结构之前,我们应该先整理好工程的外貌,将文件和类的命名进行规范,在Xcode中为我们提供了方便而强大的名称修改功能. 第一步:修改类名 将鼠标点击放在类的名称上 ...

  9. max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

    在/etc/syscurity/limits.conf 加入以下两行: elastic hard nofile 65536 elastic soft nofile  65536 #备注:elastic ...

  10. JQuery阻止冒泡事件on绑定中异常情况分析

    科普下事件冒泡以及默认行为,以下面例子举列子:     事件冒泡:当点击内部button元素时,会触发自身及外层 a的点击事件,这就是事件冒泡引起的.事件会随着 DOM 的层次结构依次向上传播. 事件 ...