操作系统基本概念

计算机硬件基本知识

从概念上讲,计算机的结构非常简单:首先布置一根总线,然后将各种硬件设备挂在总线上。所有这些设备都有一个控制设备,外部设备都由这些控制器与CPU通信。所有设备之间的涌信均需通过总线、如图所示。图中的粗线条为总线。

在这里插入图片描述

为了提高计算机的效率,人们又设计出了流水线结构,即仿照工业流水装配线,将计算机的功能部件分为多个梯级,并将计算机的每条指令分拆为同样多个步骤,使每条指令在流水线上流动,到流水线最后一个梯级时指令执行完毕。流水线上的每个梯级都可以容纳一条指令同时执行,如上图所示。

为了进一步提高计算机的效率,在流水线的基础上,人们又发明了多流水线、超标量计算和超长指令字等多指令发射机制。这些机制的发明在提升计算机效率(主要是吞吐量)的同时,也极大地增加了计算机结构的复杂性,并对操作系统和编译器都提出了更高的要求。

下图描述的是一个超标量发射的体系结构。这个结构有两队指令读取和译码单元,三个执行单元。通过一个指令保持缓冲区,就可以实现多路复用( multiplex)和反多路复用( demultiplex ),从而提高系统每个功能单元的利用率和整个系统的吞吐量。
在这里插入图片描述
除了指令执行单元外,计算机里面的另一个重要部件是指令的存放单元,称为存储架构。存储架构包括了缓存、主存、磁盘、磁带。有的情况下还存在多级缓存和外部光盘。下图描述的是一个包括寄存器的5级存储介质构成的存储架构。
在这里插入图片描述

从寄存器到磁带,每一级的存储媒介的访问延迟和容量均依次增大,而价格却依次降低。寄存器的访问速度最快,容量最小,但成本最高;磁带的访问速度最慢,容量最大,成本却最低。通过合理的搭配,可以形成一个性能价格比颇佳的存储架构。

磁盘是计算机的主要存储媒介。可以说,没有磁盘,计算机就不称其为计算机
或者说计算机的用处就要大打折扣。虽然确实存在无磁盘的计算机 ( diskless 计算机),但这些计算机都有特别之用,并不是给一般用户用的。磁盘从概念上看非常简单,每个磁盘有多块盘片,盘片两面都可以存储。下图描述的是典型的磁盘结构。
在这里插入图片描述
中断是计算机里面的一个最为重要的机制,它也是操作系统获得计算机控制权的根本保证。 没有中断,很难想象操作系统如何完成人们所赋给的任务。中断的基本原理是:设备在完成自己的任务后向CPU发出中断,CPU判断优先级,然后确定是否响应。如果响应,则执行中断服务程序,并在中断服务程序执行完后继续原来的程序。下图简单地描述了中断机制。
在这里插入图片描述
中断是很复杂的过程,中断处理过程中又可以发生中断,且还可以有所谓的软中断,即软件发出的中断。透彻理解中断对了解计算机操作系统的运行具有重要意义。因此,对中断机制不甚了解的读者请复习在计算机组成与体系结构课程中所学的中断内容。

抽象

我们已经多次提到过,操作系统提供的是一个抽象。所谓的抽象,就是在根本上存在但现实中不存在的东西。那么到底怎样理解抽象呢?

抽象来源于具体,但又超越具体。操作系统提供的抽象自然也来源于现实、就是具体的计算机硬件,CPU、内存、I/O设备等。但又超出这些现实,给人提供了强于现实的东西,使人和应用软件感觉到更多、更好的硬件存在,而且只有在操作系统层面上,一般的人才会觉得计算机是可以使用的。

另外,抽象不光是操作系统提供给用户的一个存在,它也存在于操作系统内部。操作系统内部分为不同的功能块,而不同的功能块之间互相提供的也是抽象。

内核态和用户态

就像世界上的人并不平等一样,并不是所有的程序都是平等的。世界上有的人占有资源多,有的人占有资源少,有的人来了,别人得让出资源,有的人则专门为别人让出资源。程序也是这样,有的程序可以访问计算机的任何资源,有的程序则只能访问非常受限的少量资源。而操作系统作为计算机的管理者,自然不能和被管理者享受一样的待遇。它应该享有更多的方便或特权。为了区分不同程序的不同权利,人们发明了内核态和用户态的概念。

那么什么是内核态,什么是用户态呢?只要想一想现实生活中,处于社会核心的人与处于社会边缘的人有什么区别就能明白处于核心的人拥有的资源多!因此,内核态就是拥有资源多的状态,或者说访问资源多的状态,我们也称之为特权态。相对来说,用户态就是非特权态,在此种状态下访问的资源将受到限制。

如果一个程序运行在特权态,则该程序就可以访间计算机的任何资源,即它的资源访问权限不受限制。如果一个程序运行在用户态,则其资源需求将受到各种限制。例如,如果要访问操作系统的内核数据结构,如进程表,则需要在特权态下才能办到。如果要访问用户程序里的数据,则在用户态下就可以了。

由于内核态的程序可以访问计算机的所有资源,这种程序的可靠性和安全性就显得十分重要。试想如果一个不可靠的程序在内核态下修改了操作系统的各种内核数据结构,结果会怎样呢?整个系统有可能崩溃。而运行于用户态的程序就比较简单了,如果其可靠性和安全性出了问题,其造成的损失只不过是让用户程序崩溃,而操作系统将继续运行。

很显然,内核态和用户态各有优势:运行在内核态的程序可以访问的资源多,但可靠性、安全性要求高,维护管理都较复杂;用户态程序访问的资源受限,但可靠性、安全性要求低,自然编写维护起来都较简单。一个程序到底应该运行在内核态还是用户态取决于其对资源和效率的需求。

一般来说,一个程序能够运行于用户态,就应该让它运行在用户态。 只在迫不得已的情况下,才让程序运行于内核态。

那么什么样的功能应该在内核态下实现呢?首先,CPU管理和内存管理都应该在内核态实现。这些功能可不可以在用户态下实现呢?当然能,但是不太安全。所以从保障计算机安全的角度来说,CPU和内存的管理必须在内核态实现。诊断与测试程序也需要在内核态下实现。因为诊断和测试需要访问计算机的所有资源,否则怎么判断计算机是否正常呢?输入输出管理也一样,因为要访问各种设备和底层数据结构,也必须在内核态实现。对于文件系统来说,则可以一部分放在用户态,一部分放在内核态。文件系统本身的管理,即文件系统的宏数据部分的管理,必须放在内核态,不然任何人都可能破坏文件系统的结构;而用户数据的管理,则可以放在用户态。编译器、网络管理的部分功能、编辑器用户程序,自然都可以放在用户态下执行。下图描述的是 Windows操作系统的内核态与用户态的界线。

在这里插入图片描述

态势的识别

那么计算机是如何知道现在正在运转的程序是内核态程序呢?正确作出内核态或用户态的判断对系统的正确运行至关重要。显然作出这种判断需要某种标志。这个标志就是处理器的一个状态位。这个状态位是CPU状态字里面的一个字位。 这就是说,所谓的用户态、内核态实际上是处理器的一种状态, 而不是程序的状态,我们通过设置该状态字,可以将CPU设置为内核态,或者用户态,或者其他的子态(有的CPU有更多种子态)。一个程序运行时,CPU是什么态,这个程序就运行在什么态。

内核态与用户态的实现

前面说过,内核态是特权态,而用户态是普通态。特权态下运行的程序可以访问任何资源,而用户态下的访问则受到限制。那么这种限制是如何实现的呢?

显然,要限制一个程序对资源的访问,需要对程序执行的每一条指令进行检查才能完成。而这种检查就是地址翻译。程序发出的每一条指令都要经过这个地址翻译过程。通过对翻译的控制,就可以限制程序对资源的访问。

为了给内核态程序赋予访问所有资源的特权,系统处于内核态时,内核程序可以绕过内存地址翻译而直接执行特权指令,如停机指令。这种绕过翻译的做法突破了系统对资源的控制。

在讲完进程和内存后,将再次讨论内核态与用户态的议题。

操作系统结构

操作系统的结构也和操作系统历史类似,经历了好几个阶段。在操作系统刚刚出现时,人们还没有意识到操作系统的存在,也没有将那些库函数称为操作系统。那个时候,人们想到什么功能,就把这个功能加进来,并没有对所有这些功能进行统筹兼顾的计划。自然,那个时候的操作系统也是杂乱的、无结构的。

随着操作系统的进化,人们对操作系统的认识逐步加深,操作系统慢慢变得有一些结构。各种功能归为不同的功能块,每个功能块相对独立,又经过固定的界面互相联系,任意一个功能块可以调用另一个功能块的服务。 整个操作系统本身是一个巨大单一体( monolithicalsystem),运行在内核态下,为用户提供服务,如图所示。
在这里插入图片描述

后来人们发现单一体的操作系统结构有很多缺点:功能块之间的关系复杂,修改任意功能块将导致其他所有功能块都需要修改,从而导致操作系统设计开发的困难;这种没有层次关系的网状联系容易造成循环调用,形成死锁,从而导致操作系统可靠性降低。这时候,人们想到了人类社会里面的层次关系,何不将人类熟悉的层次关系搬到操作系统设计里来,给操作系统也定义个层次关系呢?将操作系统的功能分成不同层次,低层次的功能为紧邻其上的一个层次的功能提供服务,而高层次的功能又为更高一个层次的功能提供服务。
在这里插入图片描述
从前面两张图可以看出,操作系统的所有功能都在内核态下运行。而这带来几个问题。首先,操作系统的所有服务都需要进入内核态才能使用,而从用户态转换为内核态是有时间成本的,这样就造成操作系统效率低下。 在操作系统还比较简单时这个问题并不突出,但随着操作系统功能和夏杂性的增加,这种问题就十分明显了。

其次,我们前面说过,在内核态运行的程序可以访问所有资源,因此其安全性和可靠性要求十分高。在操作系统很小时,将其设计得可靠和安全不是特别困难。再说,在操作系统历史的早期没有出现那么多的安全问题,自然安全上的考虑就不用太多。但随着操作系统越来越大,破坏者的水平越来越高,操作系统的可靠性和安全性就变得很难达到。

因此,人们又想出了一个办法只释操作系统核心中的核心放在内核态运行,其他功能都移到用户态。这样就同时提高了效率和安全性。

在这里插入图片描述
各种操作系统结构各有优缺点,但当前的趋势是第三种模式,即微内核的操作系统结构。至于这个微内核到底有多“微”,则是仁者见仁、智者见智的。

进程、内存和文件

进程是操作系统里面的核心概念。它指的是一个运动中的程序。 从名字上看,进程表示的就是进展中的程序。一个程序一旦在计算机里动起来,它就成为一个进程。操作系统对进程的管理通过进程表来实现。进程表里存放的是关于进程的一切信息。 在任何一个时候,进程所占有的全部资源,包括分配给该进程的内存、内核数据结构和软资源形成一个进程核( Core ) 。核快照(Core image)代表的是进程在某一特定时刻的状态。

如果在Linux或UNIX下编程序,当出现分段错误( segmentation fault)时,操作系统会自动进行核倒出( core dump)。核倒出”把所有计算机的状态保存在一个文件中,通过阅读这个文件的内容可以得知出界时的进程状况,从而帮助对程序的调试。

进程与进程之间可以进行通信、同步、竞争,并在一定情况下可能形成死锁。这些概念都将在接下来的文章讲到。

内存是操作系统里面的另一个核心概念。它是进程的存放场所。如何对内存进行管理,使得数据的读写具有高效率、高安全、高空间利用率和位置透明的特性是内存管理所要达到的目的。

文件是操作系统提供的外部存储设备的抽象,它是程序和数据的最终存放地点。 如何让用户的数据存放变得容易、方便、可靠和安全是文件系统要解决的问题。

系统调用

我们说过,操作系统是一个系统程序?即为别的程序提供服务的程序。那操作系统的服务是通过什么方式提供的呢?答案是系统调用( system call)。系统调用就是操作系统提供的应用程序界面(API)。用户程序通过调用这些API获得操作系统的服务。 例如,如果用户程序需要进行读磁盘操作,在C程序代码里将使用下面的语句:

result = read(fd, buffer , nbytes);

这个read函数是C语言提供的库函数,而这个库函数本身则是调用的操作系统的read系统调用。注意这里有两个read,一个是read库函数,由程序语言提供;一个是read系统调用,由操作系统提供。编译器在看到上述语句后将read库函数扩展为read系统调用。在真正执行时,操作系统将完成上述文件的读操作。

系统调用按照功能可以划分为六大类:

  • 进程控制类。
  • 文件管理类。
  • 设备管理类。
  • 内存管理类。
  • 信息维护类。
  • 通信类。

系统调用一般不在操作系统原理的课程中论述,而是在操作系统编程或系统编程的课程中论述。这里我们简单说一下系统调用的过程。系统调用分为三个阶段,分别是:

  • 参数准备阶段。
  • 系统调用识别阶段。
  • 系统调用执行阶段。

在参数准备阶段,需要使用系统服务的程序将系统调用所需要的参数,如上述例子中的fd,buffer,nbytes,压到栈上。然后调用库函数read。库函数read将系统调用read的代码放在一个约定好的寄存器里,通过陷入(trap,一种中断方式)将控制交给操作系统。由此进入到第二个阶段。操作系统获得控制后,将系统调用代码从寄存器里取出,与操作系统维护的一张系统调用表进行比较,获得系统调用read的程序体所在的内存地址。之后跳到该地址,进入到第三个阶段,执行系统调用函数。系统调用执行完毕后返回到用户程序(见图)。
在这里插入图片描述

系统调用中的参数传递

从图可以看出,read系统调用的参数压入到栈里面,即参数传递是通过栈来进行。但这并不是唯一的参数传递办法。事实上,这还不是效率最高的传递方法。效率最高的方法是将参数存放在指定的寄存器里面。由于寄存器的访问速度高于栈,这种参数传递将可以提升系统调用执行的效率。

前面一节说明了操作系统是如何给用户程序提供服务的。用户程序通过调用操作系统提供的系统调用API来获得操作系统的各种服务。但使用API需要编程。 对于不编程序的用户来说,或对于需要与操作系统进行交互的用户来说,又怎么使用操作系统的服务呢?

为这些不编程的用户,操作系统提供了一个壳( shell ) ,来与用户交互。 每个操作系统都提供某种壳,以便与用户进行交互。这个壳是覆盖在操作系统服务上面的一个用户界面,既可以是图形界面,也可以是文本界面。用户在这个界面上输入命令,操作系统则执行这些命令。当然,用户输入的命令不是直接的操作系统服务,而是所谓的utilities。utilities 的功用相当于C语言里面的库函数。因为用户不能直接调用系统调用(通过操作系统间接调用),C语言提供了库函数来解决这个问题。

一个壳的具体功能包括如下几项:

  • 显示提示符,如UNIX下的提示符通常为$和%。
  • 接受用户命令并执行。
  • 实现输入输出间接(或间接输入输出)。
  • 启动后台进程。
  • 进行工作控制。
  • 提供伪终端服务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值