• Linux操作系统是如何工作的


    一、操作系统工作的基础

      操作系统虽然极其庞大和复杂,但是它的核心思想却非常简单明了,其实它的运作只依赖于三个基本的概念:存储程序计算机、堆栈(函数调用堆栈)机制和中断机制。

    1. 存储程序计算机

      存储程序计算机就是冯·诺伊曼结构,它的核心思想就是把指令当做数据存储起来,这样的话,就不是用硬件来实现程序(以前实现不同的程序要把不同的硬件拼来拼去),从而从根本上改善了计算机的灵活性,使得计算机可以很容易地改变其程序,并在程序控制下改变其运算内容。有了这种体系结构,就可以把程序的指令存到存储器中,然后运算单元就可以从存储器中取指令,然后执行。这就达到了基本的运算的目的,并可以在一台机器上方便地执行多种程序。

    2. 堆栈(函数调用堆栈)

      能够把指令存起来,取出来,然后执行,还是不够的,因为计算的时候还需要存储很多临时的数据,这些数据中,很多并不会在整个程序的运行期一直需要,而是会随着程序的运行,动态地生成,并且稍后就可以被销毁,永不再用,所以这样的话就还需要一个动态地管理临时数据的机制,这个机制就是堆栈(函数调用堆栈)。堆是一个长期存放数据的地方,而栈则是随着函数的调用动态地变化的地方。程序员把程序分成若干个函数,函数内部的数据是随着函数的调用和返回动态地生成和销毁的(放在栈上),而函数外的数据则放在堆上,不随函数的调用自动变化。这样,计算机就提供了一种灵活地存储计算时中间结果和临时数据的机制,可以在运行时重复利用存储器资源,去完成更复杂的计算。

    3. 中断机制

      有了上面两个功能,基本的执行程序的能力就有了,也就是你把数据和程序放到存储器上,然后CPU就可以去存储器上取指令,并且根据指令去动态地操纵数据,或者改变程序的执行路径。但是,这还不够方便,因为给了CPU一个程序以后,它只能一股脑地顺着程序的指令走,没有任何办法让它动态地跟其他设备交互,如果有人想让它稍微停一下看看它的运行状态,那就办不到了。又或者CPU要跟某个速度很慢的设备交互,当前情况下,它只能串行地去跟设备交互,设备运行期间,CPU要等着,等设备运行好了,再通知CPU。这不仅效率极低,而且很多需要跟外设并发执行的程序都没办法执行。于是,就有了强大的中断机制,可以打断CPU当前程序的执行,让它去执行一下别的任务,然后再回来。这样一来,计算机的灵活性又大大提高了一节。

      OK,有了上面的三个基本条件,一个可以变更程序的、可以管理运行时的数据的、并且可以异步地与外设交互的计算机就有了。现在,即使没有操作系统,它也能比较高效地完成一个任务了。不过要注意,现在它还只能运行一个任务,要想让它并发地执行多个任务,并且比较高效地协调这些任务,那还需要操作系统的帮忙。

    单任务软件的典型架构:

    int main(int argc, char* argv[]) 
    { 
        while (1) 
        { 
            if (serialInt == 1) 
            /*有串口中断*/ 
            { 
                ProcessSerialInt(); /*处理串口中断*/ 
                serialInt = 0; /*中断标志变量清零*/ 
            } 
            if (keyInt == 1) 
            /*有按键中断*/ 
            { 
                ProcessKeyInt(); /*处理按键中断*/ 
                keyInt = 0; /*中断标志变量清零*/ 
            } 
            status = CheckXXX(); 
            switch (status) 
            { 
                ... 
            } 
            ... 
        } 
    } 
                

    二、操作系统是如何工作的

      有了上述基础,我们就可以让计算机来运行一个操作系统了。有了操作系统,我们就可以在计算机上同时运行大批的程序,并且操作系统会帮我们比较高效、安全地管理这些程序。具体来说,当计算机的硬件基本初始化好,可以运行一个程序的时候,就运行start_kernel,完成操作系统本身的初始化,并且最后会启动一个init进程,今后所有用户想要执行的程序,都直接或间接地从这个init进程派生而来。

      当用户的进程在执行的时候,如果来了一个中断,那么就会进入内核态,先把它的esp和eip存入内核栈,然后SAVE_ALL把CPU的一些寄存器存入内核栈,然后就进行中断处理,中断处理的最后会调用switch_to宏,切换到另一个进程继续执行。新执行的程序会接着从它上一次被switch_to切换出去的地方继续执行,很可能是restore_all和iret,也就是从内核态切换出来,在用户态继续执行用户程序。我们的计算机在运行的时候,就是如此不断往复的一个流程。

    三、参考资料

    维基百科:冯诺依曼结构http://zh.wikipedia.org/wiki/%E5%86%AF%C2%B7%E8%AF%BA%E4%BC%8A%E6%9B%BC%E7%BB%93%E6%9E%84

    《LINUX 设备驱动开发详解》作者:华清远见 http://download.farsight.com.cn/download/ebooks/Farsight10-LinuxDriver-01.pdf

  • 相关阅读:
    Vue demo
    netcore使用IOptions
    CS0656 缺少编译器要求的成员“Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create”
    vs删除空白行 注释
    RabbitMQ入门
    EF 大数据量批量处理
    常用链接字符串
    DEA使用git提交代码时,点了commit之后卡死在performing code analysis部分,或者performing code analysis结束后没有进入下一步操作。
    Ubuntu16.04安装MySQL5.7
    ubuntu16.04源码编译安装nginx1.14.2
  • 原文地址:https://www.cnblogs.com/yding9/p/3162503.html
Copyright © 2020-2023  润新知