“平安的祝福 + 原创作品转载请注明出处 + 《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. catalan number

    http://blog.csdn.net/yutianzuijin/article/details/13161721

  2. springMVC中文乱码问题

    1)中文JSP页面编码统一为UTF-8后,页面可以正常显示,但从数据库中获取的数据依然显示乱码(比如下拉表单的数据): 2)当使用了springMVC提供的编码Filter拦截处理后,表单数据.从数据 ...

  3. 通过syslog接收远程日志

    通过syslog接收远程日志   通过syslog接收远程主机的日志,需要做一些环境配置.   客户机A通过syslog将日志信息发送到服务主机B(或称日志采集服务器).以下说明配置过程(我的实验环境 ...

  4. 【leetcode】 search Insert Position(middle)

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  5. Android 录音

    想要实现wav格式的编码时我们也就不能再使用MediaRecorder,而只能使用AudioRecord进行处理

  6. ListView + PopupWindow实现滑动删除

    原文:ListView滑动删除 ,仿腾讯QQ(鸿洋_) 文章实现的功能是:在ListView的Item上从右向左滑时,出现删除按钮,点击删除按钮把Item删除. 看过文章后,感觉没有必要把dispat ...

  7. set -x 跟踪脚本执行信息

    注意set -x其中"-"与"x"之间没有空格 [root@GitLab sh]# ./sx.sh heelo + a=heelo + echo heelo h ...

  8. 与你相遇好幸运,Linux常用命令

    开机挂载硬盘 cat  /etc/fstab /dev/sda1  /mnt/sda1 ext3    defaults    0  0 挂载硬盘 mount  /dev/sdb5 /home/dis ...

  9. linux cpuInfo

    转自:http://blog.csdn.net/lgstudyvc/article/details/7889364   /proc/cpuinfo文件分析 在Linux系统中,提供了proc文件系统显 ...

  10. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...