版权归原作者所有,如有侵权,请联系我们

[科普中国]-执行系统功能

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

简介

在计算机系统中,通常运行着两类程序:系统程序和应用程序,为了保证系统程序不被应用程序有意或无意地破坏,为计算机设置了两种状态:系统态(也称为管态或核心态)和用户态(也称为目态)。操作系统在系统态运行,而应用程序只能在用户态运行。执行系统功能是指执行进程管理、内存管理等系统功能,或指应用程序请求操作系统执行系统特有的功能,即通过系统调用来实现。

常见系统功能进程管理在传统的多道程序系统中,处理机的分配和运行都是以进程为基本单位,因而对处理机的管理可归结为对进程的管理;在引入了线程的 OS 中,也包含对线程的管理。处理机管理的主要功能是创建和撤消进程(线程),对诸进程(线程)的运行进行协调,实现进程(线程)之间的信息交换,以及按照一定的算法把处理机分配给进程(线程)1。

进程控制

在传统的多道程序环境下,要使作业运行,必须先为它创建一个或几个进程,并为之分配必要的资源。当进程运行结束时,立即撤消该进程,以便能及时回收该进程所占用的各类资源。进程控制的主要功能是为作业创建进程,撤消已结束的进程,以及控制进程在运行过程中的状态转换。在现代 OS 中,进程控制还应具有为一个进程创建若干个线程的功能和撤消(终止)已完成任务的线程的功能。

进程同步

前已述及,进程是以异步方式运行的,并以人们不可预知的速度向前推进。为使多个进程能有条不紊地运行,系统中必须设置进程同步机制。进程同步的主要任务是为多个进程(含线程)的运行进行协调。有两种协调方式:

(1) 进程互斥方式。这是指诸进程(线程)在对临界资源进行访问时,应采用互斥方式;

(2) 进程同步方式。这是指在相互合作去完成共同任务的诸进程(线程)间,由同步机构对它们的执行次序加以协调。

为了实现进程同步,系统中必须设置进程同步机制。最简单的用于实现进程互斥的机制是为每一个临界资源配置一把锁 W, 当锁打开时, 进程(线程)可以对该临界资源进行访问;而当锁关上时,则禁止进程(线程)访问该临界资源。而实现进程同步的最常用的机制则是信号量机制,我们将在第二章中做详细介绍。

进程通信

在多道程序环境下,为了加速应用程序的运行,应在系统中建立多个进程,并且再为一个进程建立若干个线程,由这些进程(线程)相互合作去完成一个共同的任务。而在这些进程(线程)之间,又往往需要交换信息。例如,有三个相互合作的进程,它们是输入进程、计算进程和打印进程。输入进程负责将所输入的数据传送给计算进程;计算进程利用输入数据进行计算,并把计算结果传送给打印进程;最后,由打印进程把计算结果打印出来。进程通信的任务就是用来实现在相互合作的进程之间的信息交换。当相互合作的进程(线程)处于同一计算机系统时,通常在它们之间是采用直接通信方式,即由源进程利用发送命令直接将消息(Message)挂到目标进程的消息队列上,以后由目标进程利用接收命令从其消息队列中取出消息。

调度

在后备队列上等待的每个作业都需经过调度才能执行。在传统的操作系统中,包括作业调度和进程调度两步。

(1) 作业调度。作业调度的基本任务是从后备队列中按照一定的算法,选择出若干个作业,为它们分配运行所需的资源(首先是分配内存)。在将它们调入内存后,便分别为它们建立进程,使它们都成为可能获得处理机的就绪进程,并按照一定的算法将它们插入就绪队列。

(2) 进程调度。 进程调度的任务是从进程的就绪队列中, 按照一定的算法选出一个进程,把处理机分配给它,并为它设置运行现场,使进程投入执行。值得提出的是,在多线程 OS中,通常是把线程作为独立运行和分配处理机的基本单位,为此,须把就绪线程排成一个队列,每次调度时,是从就绪线程队列中选出一个线程,把处理机分配给它。

内存管理根据帕金森定律:“你给程序再多内存,程序也会想尽办法耗光”,因此程序员通常希望系统给他无限量且无限快的内存。大部分的现代电脑内存架构都是层次结构式的,最快且数量最少的寄存器为首,然后是缓存、内存以及最慢的磁盘存储设备。而操作系统的内存管理提供查找可用的记忆空间、配置与释放记忆空间以及交换内存和低速存储设备的内含物……等功能。此类又被称做虚拟内存管理的功能大幅增加每个进程可获得的记忆空间(通常是4GB,即使实际上RAM的数量远少于这数目)。然而这也带来了微幅降低运行效率的缺点,严重时甚至也会导致进程崩溃。

内存管理的另一个重点活动就是借由CPU的帮助来管理虚拟位置。如果同时有许多进程存储于记忆设备上,操作系统必须防止它们互相干扰对方的内存内容(除非通过某些协议在可控制的范围下操作,并限制可访问的内存范围)。分区内存空间可以达成目标。每个进程只会看到整个内存空间(从0到内存空间的最大上限)被配置给它自己(当然,有些位置被操作系统保留而禁止访问)。CPU事先存了几个表以比对虚拟位置与实际内存位置,这种方法称为标签页配置。

借由对每个进程产生分开独立的位置空间,操作系统也可以轻易地一次释放某进程所占据的所有内存。如果这个进程不释放内存,操作系统可以结束进程并将内存自动释放。

磁盘与文件系统所谓的文件系统,通常指称管理磁盘数据的系统,可将数据以目录或文件的型式存储。每个文件系统都有自己的特殊格式与功能,例如日志管理或不需磁盘重整。

操作系统拥有许多种内置文件系统。例如Linux拥有非常广泛的内置文件系统,如ext2、ext3、ext4、ReiserFS、Reiser4、GFS、GFS2、OCFS、OCFS2、NILFS与Google文件系统。Linux也支持非原生文件系统,例如XFS、JFS、FAT家族与NTFS。另一方面,Windows能支持的文件系统只有FAT12、FAT16、FAT32、EXFAT与NTFS。NTFS系统是Windows上最可靠与最有效率的文件系统。其他的FAT家族都比NTFS老旧,且对于文件长度与分区磁盘能力都有很大限制,因此造成很多问题。而UNIX的文件系统多半是UFS,而UNIX中的一个分支Solaris最近则开始支持一种新式的ZFS。

大部分上述的文件系统都有两种建置方法。系统可以以日志式或非日志式建置。日志式文件系统可以以较安全的手法运行系统恢复。如果一个没有日志式建置的文件系统遇上突然的系统崩溃,导致数据创建在一半时停顿,则此系统需要特殊的文件系统检查工具才能撤消;日志式则可自动恢复。微软的NTFS与Linux的ext3、ext4、reiserFS与JFS都是日志式文件系统。

每个文件系统都实现相似的目录/子目录架构,但在相似之下也有许多不同点。微软使用“\”符号以创建目录/子目录关系,且文件名称忽略其大小写差异;UNIX系统则是以“/”创建目录架构,且文件名称大小写有差异。(其实这是给system call看的,"/"或"\"并不实际存在硬盘)

网络许多现代的操作系统都具备操作主流网络通信协议TCP/IP的能力。也就是说这样的操作系统可以进入网络世界,并且与其他系统分享诸如文件、打印机与扫描仪等资源。

许多操作系统也支持多个过去网络启蒙时代的各路网络通信协议,例如IBM创建的系统网络架构、DEC在它所生产的系统所设置的DECnet架构与微软为Windows制作的特殊通信协议。还有许多为了特殊功能而研发的通信协议,例如可以在网络上提供文件访问功能的NFS系统。现今大量用于影音流(Streaming media)及游戏消息发送的UDP协议等。

安全大多数操作系统都含有某种程度的信息安全机制。信息安全机制主要基于两大理念:

操作系统提供外界直接或间接访问数种资源的管道,例如本地端磁盘驱动器的文件、受保护的特权系统调用、用户的隐私数据与系统运行的程序所提供的服务。

操作系统有能力认证资源访问的请求。允许通过认证的请求并拒绝无法通过的非法请求,并将适当的权力授权(Authorization)给此请求。有些系统的认证机制仅简略地把资源分为特权或非特权,且每个请求都有独特的身份辨识号码,例如用户名。资源请求通常分成两大种类:

内部来源:通常是一个正在运行的程序发出的资源请求。在某些系统上,一个程序一旦可运行就可做任何事情(例如DOS时代的病毒),但通常操作系统会给程序一个识别代号,并且在此程序发出请求时,检查其代号与所需资源的访问权限关系。

外部来源:从非本地端电脑而来的资源请求,例如远程登录本机电脑或某些网络连接请求(FTP或HTTP)。为了识别这些外部请求,系统也许会对此请求提出认证要求。通常是请求输入用户名以及相对应的密码。系统有时也会应用诸如磁卡或生物识别数据的它种认证方法。在某些例子,例如网络通信上,通常不需通过认证即可访问资源(例如匿名访问的FTP服务器或P2P服务)。

除了允许/拒绝形式的安全机制,一个高安全档次的系统也会提供记录选项,允许记录各种请求对资源访问的行为(。

肇因于军方与商业组织将敏感数据记录在电脑上,安全机制在操作系统历史上是一个被长久关注与讨论的问题。美国国防部(DoD)便创立了《可信赖之计算机系统评鉴程序》(TCSEC),此手册确立了评鉴安全机制成效的基本原则。这对操作系统作者来说非常重要,因为TCSEC是用于评鉴、分类与选拔出用于处理、存储与获取敏感或机密数据的电脑系统的标准程序。

内部通讯安全

内部信息安全可视为防止正在运行的程序任意访问系统资源的手段。大多操作系统让普通程序可直接操作电脑的CPU,所以产生了一些问题,例如怎样把可如操作系统一样处理事务、运行同样特殊指令的程序强迫停止,毕竟在此情境下,操作系统也只是另一个平起平坐的程序。为通用操作系统所生产的CPU通常于硬件层级上实践了一定程度的特殊指令保护概念。通常特权层级较低的程序想要运行某些特殊指令时会被阻断,例如直接访问像是硬盘之类的外部设备。因此,程序必须得经由询问操作系统,让操作系统运行特殊指令来访问磁盘。因此操作系统就有机会检查此程序的识别身份,并依此接受或拒绝它的请求。

在不支持特殊指令架构的硬件上,另一个也是唯一的保护方法,则是操作系统并不直接利用CPU运行用户的程序,而是借由模拟一个CPU或提供一P-code机系统(伪代码运行机),像是Java一样让程序在虚拟机上运行。

内部安全机制在多用户电脑上特别重要:它允许每个系统用户拥有自己个人的文件与目录,且其他用户不能任意访问或删除。因为任何程序都可能绕过操作系统的监控,更有可能绕过侧录程序的监控,拥有强制力的内部安全机制在侧录引导时也非常重要。

外部通讯安全

通常一个操作系统会为其他网络上的电脑或用户提供(主持)各种服务。这些服务通常借由端口或操作系统网络地址后的数字接入点提供。通常此服务包括提供文件共享(NFS)、打印共享、电子邮件、网页服务与文件传输协议(FTP)。 外部信息安全的最前线,是诸如防火墙等的硬件设备。在操作系统内部也常设置许多种类的软件防火墙。软件防火墙可设置接受或拒绝在操作系统上运行的服务与外界的连接。因此任何人都可以安装并运行某些不安全的网络服务,例如Telnet或FTP,并且设置除了某些自用通道之外阻挡其他所有连接,以达成防堵不良连接的机制。

用户界面今日大部分的操作系统都包含图形用户界面(GUI)。有几类较旧的操作系统将图形用户界面与内核紧密结合,例如最早的Windows与Mac OS实现产品。此种手法可提供较快速的图形回应能力,且实现时不需切割模块因而较为省工,但是会有强烈副作用,例如图形系统崩溃将导致整个系统崩溃,例如蓝屏死机。许多近代的操作系统已模块化,将图形接口的副系统与内核分开(已知Linux与Mac OS X原先就是如此设计,而某些扩充版本的Windows终于也采用此手法)。

许多操作系统允许用户安装或创造任何他们喜欢的图形用户界面[5]。大部分的Unix与Unix派生系统(BSD、Linux与Minix)通常会安装X Window系统配合GNOME或KDE桌面环境。而某些操作系统就没有这么弹性的图形用户界面,例如Windows。这类的操作系统只能通过外加的程序来改变其图形用户界面,甚至根本只能改变诸如菜单风格或颜色配置等部分[来源请求]。

图形用户界面与时并进,例如Windows在每次新版本上市时就会将其图形用户界面改头换面,而Mac OS的GUI也在Mac OS X上市时出现重大转变。

驱动程序所谓的驱动程序(Device driver)是指某类设计来与硬件交互的电脑软件。通常是一设计完善的设备交互接口,利用与此硬件连接的电脑汇排流或通信子系统,提供对此设备下令与接收信息的功能;以及最终目的,将消息提供给操作系统或应用程序。驱动程序是针对特定硬件与特定操作系统设计的软件,通常以操作系统内核模块、应用软件包或普通计算机程序的形式在操作系统内核底下运行,以达到通透顺畅地与硬件交互的效果,且提供硬件在处理异步的时间依赖性接口(asynchronous time-dependent hardware interface)时所需的中断处理函数。

设计驱动程序的主要目的在于操作抽象化,任何硬件模块,既使是同一类的设备,在硬件设计面上也有巨大差异。厂商推出的较新模块通常更可靠更有效率,控制方法也会有所不同。电脑与其操作系统每每不能预期那些现有与新设备的变异之处,因此无法知道其操作方法。为解决此问题操作系统通常会主动制订每种设备该有的操作方式,而驱动程序功能则是将那些操作系统制订的行为描述,转译为可让设备了解的自定义操作手法。

理论上适合的驱动程序一旦安装,相对应的新设备就可以无误地运行。此新驱动程序可以让此设备完美地切合在操作系统中,让用户察觉不到这是操作系统原本没有的功能。

系统调用概述所谓系统调用就是用户在程序中调用操作系统所提供的一些子功能,系统调用可以被看做特殊的公共子程序。系统中的各种共享资源都由操作系统统一掌管,因此在用户程序中,凡是与资源有关的操作(如存储分配、进行I/0传输以及管理文件等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。通常,一个操作系统提供的系统调用命令有几十乃至上百条之多。

典型实现Linux 的系统调用通过 int 80h 实现,用系统调用号来区分入口函数。操作系统实现系统调用的基本过程是:

应用程序调用库函数(API);

API 将系统调用号存入 EAX,然后通过中断调用使系统进入内核态;

内核中的中断处理函数根据系统调用号,调用对应的内核函数(系统调用);

系统调用完成相应功能,将返回值存入 EAX,返回到中断处理函数;

中断处理函数返回到 API 中;

API 将 EAX 返回给应用程序

应用程序调用系统调用的过程是:

把系统调用的编号存入 EAX;

把函数参数存入其它通用寄存器;

触发 0x80 号中断(int 0x80)。