zoukankan      html  css  js  c++  java
  • 转:那些经典的软件(一):我眼中的操作系统

     

        在我刚刚学习操作系统这门课,甚至学完之后,我学习的这些理论的知识,感觉始终与我们日常在用的 *nux 和windows 差别非常非常大,感觉缺少一个桥梁去真正的连通理论上的东西和真正的实物。于是我写下这篇博文,希望能使我对理论的知识与平时使用的工具产生一点点感性的 认识。

        由于本文并非操作系统教材,操作系统教材中涉及到的内容我都尽量的简写,想要了解,就去读教材去吧。

    开机启动
     
        1.当计算机电源被打开时,它会进行加电自检(POST),然后寻找启动盘,直到 BIOS 找到一个引导扇区
        2.BIOS 将引导扇区的内容读入到内存的某一位置,然后跳转到这一位置开始执行这段代码
        3.这段代码再从硬盘中找到 loader,并将其读入内存,然后再跳转到 loader 开始执行
        4.loader 再找到 kernel,并将其读入内存。loader 使 CPU 跳入保护模式
        5.调整 kernel 在内存中的位置,然后跳转到 kernel 开始执行
        6.开机启动过程结束,系统开始运行
     
    进程
     

        进程是计算机中很成功的一个抽象,把一些可运行的代码和资源抽象成一个类似工厂的地方。有自己独立的资源,只要把CPU 给了这个进程,进程没有因为其他原因(比如请求 I/O)而阻塞,那么这个进程就运行了。

        比如开机启动过程结束以后,内核开始运行,运行的就是一个进程,是内核的初始化进程,这个进程会将整个计算机为用户准备好,启动一些内核支持的服务,比如内存的分页,文件系统的识别等等。

        每运行一个程序,这个程序就需要至少一个进程。

        操作系统需要有一个进程调度的模块,对进程的调度进行控制,进程的调度算法很重要。

        进程有三种状态:执行(正在运行)、

                                    阻塞(缺少某些资源,比如需要写某文件,该文件正在被别人写着)、

                                    就绪(缺 CPU,把 CPU 给了这个进程,就变成执行状态了)。

        有一个数据结构记录这个进程的状态,当进程被挂起的时候,进程信息就被写入到这个数据结构中保存,等到进程重新启动的时候,这些信息重新被读出来。进程运 行需要 CPU 和内存,每个进程都有自己独立的内存空间,所以只要把 CPU 的所有寄存器的值保存起来,就可以了。这个数据结构,很多书中叫做进程控制块。

        这样,有了调度算法,又有了多进程,每个进程可以干不同的事情,好像就有点操作系统大概的样子了。就拿windows来说,有的进程是负责图形化界面中的 窗口的,然后我们就能看到 windows 窗口,图形界面的布局等等,这个程序可能叫做窗口管理器。有的进程负责监控键盘和鼠标的行为,那我们就能够利用键盘和鼠标这些输入设备进行某些该系统该程 序支持的行为。

        当然,由于进程间可能涉及到一些同步的问题,就会需要锁机制,需要信号量,具体内容,欲详细了解,任何一本操作系统的教材都会讲。至于更多的,创建子进程,进程间通信等等内容,也都有很多经典的书籍讲,比如 APUE。

     
        输入/输出

        没有输入设备,我们是没有办法操作电脑的,很典型的一个输入设备就是键盘。下面我们说说键盘。在键盘中存在一个叫键盘编码器的芯片,它的作用就是监视键盘 的输入,并把适当的数据发送给计算机。在主板上还有一个键盘控制器用来接受和解码来自键盘的数据,并于软件等通信。敲击键盘有两个方面:动作(按下、按住

    放开)和内容(不同的按键)。敲击键盘会产生一个叫扫描码的编码,扫描码会被放置在输入缓冲区下。取出缓冲区的内容,就能够知道键盘输入的是什么了。貌似这就是传说中的键盘驱动。

        输出设备的话,显示器就非常典型了。显示其实是一个非常复杂的部分,显示适配器可以被设置成不同的模式,用来显示更多的色彩、更华丽的图像和动画。当我们 欣赏色彩斑斓的图形界面的时候,肯定知道要从头实现它一定是不容易的。不过我知道的不多,就只能说说最基本的东西。我理解的就是,告诉计算机,从显存的哪 一个部分开始显示,显示到哪一个部分结束。显示器就会显示显存中相应的位置。那么每个显存中存的又是什么呢,在默认的情况下,屏幕上每一个字符对应的2字 节定义。第一个字节存这个字符的前景背景色,第二个字符存这个字符的 ASCII 码,按照这样的规则,显示器就能够显示出字符以及其色彩了。至于图像是怎么显示的,想要探知的读者请自己查阅资料了。有熟悉 linux 的读者可能知道,alt + ctrl + (F1 | F2 | F3) 等等 就能够切换到不同的 tty 上,这些 tty 可以显示不同的内容,其实就是读的显存中的不同的位置,然后就可以显示出不同的内容。

        输入输出操作,肯定就少不了硬盘上的 I/O,其实对硬盘的控制,也有相应的端口。因为硬件厂商为了广大程序员能使用他们的设备,肯定要指定相应的标准,开发好相应的接口给人用的,像硬盘的分 区表,就存在硬盘上的固定位置,方便大家都能找到。对硬盘控制器的操作是通过 I/O 端口来进行,这段端口分为两组,分别是命令块寄存器和控制块寄存器。想要控制硬盘,只要向命令块寄存器写入正确的值,再通过控制块寄存器发送命令就可以 了。只要有了硬盘的驱动程序,使用驱动程序提供的接口,我们就能够对硬盘进行操作了。磁盘调度算法就是用在这里面的。关于硬盘的什么 MBR分区、GPT分区方式神马的,想了解的读者请查阅资料去吧。

    文件系统
     

       说到文件系统的话,就是组织硬盘上各种东西的一个管理的方式。把硬盘上的各种数据,抽象出来,让用户看到各种目录结构,各种文件。有时候可以理解,文件系统就是访问数据的一种界面,当然它也包括数据向存储设备的存储等功能。

        所以文件系统都会有文件的信息(比如占用哪些扇区),扇区使用情况,文件的索引,还有一些限制(比如每个目录下最多多少文件,目录深度最多多少层)等等内容。

        至于说到文件嘛,大家每天都能接触到,文件类型、读写执行权限等等,像 linux 里面,设备都是文件,这里就不细说了。

        至于创建文件,读写文件,系统会提供相应的系统调用接口。比如 *nux 的 open()、write()、read()、close() 系统调用。各种程序需要创建文件读写文件之类的功能,都是需要系统的支持。

     
    内存管理
     

        内存管理首当其冲的问题就是,当一个程序开始运行,操作系统如何给这个程序分配内存。这就是内存分配方式,同样每本操作系统教材都会讲具体算法,这里就不再赘述。

        由于物理内存并不是很容易管理,所以在计算机中,操作系统都将内存抽象成线性的,也就是大家常说的内存地址。根据一定的算法,就能够算出这个地址所在的物 理地址。对上层来说,内存都是线性的,容易理解多了。为了管理内存,常常都会有分页、分段等方式去管理,同样每本操作系统教材都会讲。还会讲一些当内存不 够用了之后,把内存中的某些页面置换的算法。

        说到内存管理,大家肯定会想到 malloc 函数。其实 malloc 函数不正是内存分配机制的最典型的实例嘛。我记得 malloc 应该是调用的 brk() 这个系统调用的。

     
    程序执行

        以前,我就很纠结,这一个个程序都是怎么开始运行的啊?直到我见到了 exec() 这个系统调用,原理大概就是创建一个进程,然后用程序的可执行代码把这个进程的东西给覆盖掉,这样执行的就是这个程序的代码啦~之后不论是这个程序继续利 用系统的接口创建子进程也好,还是自己有什么内存分配的需求,还是对硬盘有 I/O 操作,还是向终端显示,都可以做到了,因为这个操作系统支持这些功能。

     
    尾声
     

        有了以上提及的以及很多未能提及的功能,我们就可以基于操作系统提供的这些系统调用来实现各种各样的应 用,满足客户用户的各种各样的需求,这就是操作系统的作用。    我以前不懂操作系统这门课和我们用的操作系统到底有什么关系,随着见的多了,系统调用用的多了,慢慢有了一点点感觉。操作系统这门课讲的其实就是操作系统 的设计以及其中运用到的某些重要的算法。

        很多人都说,操作系统是一个程序员的基础知识,一款软件的设计,为什么值得那么多的程序员去学习呢,甚至是本科生必修课程?我认为可能是因为所有的程序员 都会接触到,用到操作系统;也可能是因为,历代多少卓越的程序员的智慧都集中在操作系统这款软件中,我们是站在巨人的肩膀上。

        参考书籍为《计算机操作系统(第三版)》与 《Orange's 一个操作系统的实现》。

        本文是 iddmx 对于操作系统的一点点的见解,由于水平有限,如有偏差错误的地方,请您指正!

        如果对您有所帮助,请点击 “推荐” 按钮,谢谢!

    转自:http://www.cnblogs.com/iddmx/p/3144187.html

  • 相关阅读:
    Java8简明教程(转载)
    Android开源代码分享
    Android关联源码support-v4的问题解决
    自定义控件的自定义的属性attrs.xml下的declare-styleable中format详解
    获得 LayoutInflater 实例的三种方式
    退出telnet
    Relay log read failure
    MySQL --log-slave-updates
    MySQL --slave-skip-errors
    MySQL 5.1.63 单机配置多实例(简单配置)
  • 原文地址:https://www.cnblogs.com/hackerl/p/3145003.html
Copyright © 2011-2022 走看看