UNIX分时系统(1974)

2020-10-16 19:51:19

注:这不是我的文章。这是一篇经典论文,最初由丹尼斯·M·里奇和肯·汤普森于1974年发表在“美国医学会通讯”(Communications Of The ACM)上。蓝色突出显示/注释是我自己的。

UNIX是适用于数字设备公司PDP-11/40和11/45计算机的通用、多用户、交互式操作系统。它提供了许多即使在较大的操作系统中也很少见的功能,包括:(1)包含可拆卸卷的分层文件系统;(2)兼容的文件、设备和进程间I/O;(3)启动异步进程的能力;(4)可按用户选择的系统命令语言;以及(5)包括十几种语言的100多个子系统。本文讨论了文件系统和用户命令接口的性质和实现。

UNIX有三个版本。最早的版本(大约1969-70年)在数字设备公司的PDP-7和-9计算机上运行。第二个版本在未受保护的PDP-11/20计算机上运行。本文仅介绍PDP-11/40和/45[l]系统,因为它更现代,而且它与较旧的UNIX系统的许多不同之处在于重新设计了发现有缺陷或缺失的功能。

自从PDP-11UNIX在1971年2月投入使用以来,大约有40个装置投入使用;它们通常比这里描述的系统小。他们大多从事专利申请和其他文本材料的准备和格式化、从贝尔系统内的各种交换机收集和处理故障数据,以及记录和检查电话服务订单等应用。我们自己的设备主要用于研究操作系统、语言、计算机网络和计算机科学的其他主题,也用于文档准备。

也许UNIX最重要的成就是证明了一个用于交互使用的功能强大的操作系统无论在设备上还是在人力上都不需要昂贵:UNIX可以在成本低至4万美元的硬件上运行,而且在主要系统软件上花费的时间不到两个工年。然而,UNIX包含许多即使在更大的系统中也很少提供的特性。然而,希望UNIX的用户会发现,该系统最重要的特点是它的简单、优雅和易于使用。

UNIX最重要的成就是证明了一个强大的操作系统不需要昂贵的设备和人力,但UNIX的用户会发现该系统最重要的特点是它的简单、优雅和易于使用。

除了系统本身,UNIX下可用的主要程序有:汇编器、基于QED[2]的文本编辑器、链接加载器、符号调试器、具有类型和结构(C)的类似BCPL[3]语言的编译器、BASIC方言解释器、文本格式化程序、Fortran编译器、SNOBOL解释器、自上而下编译程序(TMG)[4]、自下而上编译程序(YACC)、格式字母生成器、宏处理器(M6)[5]和置换索引程序。

还有大量的维护、实用、娱乐和新奇项目。所有这些程序都是本地编写的。值得注意的是,该系统完全是自给自足的。所有UNIX软件都在UNIX下维护;同样,UNIX文档由UNIX编辑器和文本格式化程序生成和格式化。

在其上实现我们的UNIX安装的PDP-11/45是一台16位字(8位字节)的计算机,具有144K字节的核心内存;UNIX占用42K字节。但是,该系统包括非常多的设备驱动程序,并为I/O缓冲区和系统表分配了大量空间;能够运行上述软件的最小系统总共只需要50K字节的内核。

PDP-11有一个1M字节的固定磁头磁盘,用于文件系统存储和交换,四个移动磁头磁盘驱动器,每个移动磁头驱动器在可移动磁盘盒上提供2.5M字节,以及一个使用可移动40M字节磁盘组的单个移动磁头磁盘驱动器。还有高速纸带读取器-打孔机、九轨磁带和D-磁带(可以寻址和重写单个记录的各种磁带设备)。除了控制台打字机,还有14个连接到100系列数据集的变速通信接口和一个主要用于将打印输出假脱机到公用行式打印机的201数据集接口。还有几种独一无二的设备,包括PicturePhone®接口、语音响应单元、语音合成器、照排机、数字交换网络和在Tektronix 611存储管显示器上生成矢量、曲线和字符的卫星PDP-11/20。

UNIX软件的大部分是用上述C语言编写的[6]。操作系统的早期版本是用汇编语言编写的,但在1973年夏天,它被用C语言重写。新系统的大小大约比旧系统大三分之一。由于新系统不仅更容易理解和修改,而且还包括许多功能改进,包括多道程序设计和在几个用户程序之间共享可重入代码的能力,我们认为这种大小的增加是可以接受的。

S:请注意该报是如何看待文件的重要性的。UNIX通过文件公开所有功能。

UNIX最重要的工作是提供文件系统。从用户的角度看,有三种文件:普通磁盘文件、目录文件和特殊文件。

文件包含用户放在其上的任何信息,例如符号或二进制(对象)程序。系统不需要特定的结构。文本文件只由一个字符串组成,各行由换行符分隔。二进制程序是字序列,因为当程序开始执行时,它们将出现在核心存储器中。一些用户程序以更具结构的方式操作文件:汇编器生成特定格式的目标文件,而加载器需要特定格式的目标文件。但是,文件的结构是由使用它们的程序控制的,而不是由系统控制的。

文件包含用户放在其上的任何信息,例如符号或二进制(对象)程序。系统不需要特定的结构。

目录提供了文件名和文件本身之间的映射,从而在整个文件系统上归纳出一种结构。每个用户都有自己的文件目录;他还可以创建子目录来包含方便地一起处理的文件组。目录的行为与普通文件完全相同,不同之处在于它不能被非特权程序写入,因此系统控制目录的内容。但是,具有适当权限的任何人都可以像读取任何其他文件一样读取目录。

目录提供了文件名和文件本身之间的映射,从而在整个文件系统上归纳出一种结构。

系统维护几个目录供自己使用。其中之一是根目录。通过通过目录链跟踪路径直到到达所需文件,可以找到系统中的所有文件。这类搜索的起点通常是根。另一个系统目录包含提供给一般用途的所有程序;即所有命令。然而,正如将看到的那样,程序决不一定要驻留在该目录中才能执行。

文件按14个或更少字符的序列命名。当向系统指定文件名时,它可以是路径名的形式,路径名是由斜杠/分隔并以文件名结尾的目录名序列。如果序列以斜杠开头,则从根目录开始搜索。名称/alpha/beta/Gamma会导致系统在根目录中搜索目录alpha,然后在alpha中搜索beta,最后在beta中查找Gamma。Gamma可以是普通文件、目录或特殊文件。作为一种限制情况,名称/指的是根本身。

路径名不以/开头会导致系统在用户的当前目录中开始搜索。因此,名称alpha/beta指定当前目录的子目录alpha中名为beta的文件。最简单的名称(例如alpha)指的是在当前目录中找到的文件。作为另一种限制情况,空文件名指的是当前目录。

相同的非目录文件可能以不同的名称出现在多个目录中。此功能称为链接;文件的目录条目有时称为链接。UNIX与允许链接的其他系统的不同之处在于,所有指向文件的链接都具有相同的状态。也就是说,文件不存在于特定目录中;文件的目录条目仅由其名称和指向实际描述该文件的信息的指针组成。因此,文件独立于任何目录条目而存在,尽管实际上使文件随着指向它的最后一个链接一起消失。

UNIX与允许链接的其他系统的不同之处在于,所有指向文件的链接都具有相同的状态。

每个目录始终至少有两个条目。每个目录中的名称指的是目录本身。因此,程序可以读取该名称下的当前目录。而不知道它的完整路径名。这个名字..。按照惯例,它指的是出现它的目录的父目录,也就是说,它是在其中创建的目录。

目录结构被约束为具有根树的形式。除了特殊的条目。和..,每个目录必须恰好作为一个条目出现在另一个目录中,即其父目录。这样做的原因是简化了访问目录结构的子树的程序的编写,更重要的是,避免了层次结构各部分的分离。如果允许指向目录的任意链接,则很难检测到从根到目录的最后一次连接何时被切断。

特殊文件构成了UNIX文件系统最不寻常的功能。UNIX支持的每个I/O设备至少与一个这样的文件相关联。特殊文件的读写方式与普通磁盘文件一样,但读写请求会激活相关设备。每个特殊文件的条目驻留在目录/dev中,尽管可以像普通文件一样链接到这些文件之一。因此,例如,要打孔纸带,可以在文件/dev/ppt上写入。每个通信线路、每个磁盘、每个磁带机和物理核心内存都有特殊的文件。当然,活动磁盘和核心特殊文件受到保护,不会被任意访问。

特殊文件构成了UNIX文件系统最不寻常的功能。UNIX支持的每个I/O设备至少与一个这样的文件相关联。

以这种方式处理I/O设备有三个好处:文件和设备I/O尽可能相似;文件名和设备名具有相同的语法和含义,因此可以向期望文件名作为参数的程序传递设备名;最后,特殊文件受到与普通文件相同的保护机制。

尽管文件系统的根始终存储在同一设备上,但整个文件系统层次结构不必驻留在此设备上。有一个挂载系统请求,它有两个参数:现有普通文件的名称,以及直接访问特殊文件的名称,该文件的相关存储卷(例如磁盘组)应该具有包含其自己的目录分层结构的独立文件系统的结构。挂载的效果是使对之前普通文件的引用改为引用可移动卷上的文件系统的根目录。实际上,mount用一个全新的子树(存储在可移动卷上的层次结构)替换了层次结构树(普通文件)的叶子。挂载后,可移动卷上的文件和永久文件系统中的文件几乎没有区别。例如,在我们的安装中,根目录驻留在固定磁头磁盘上,而包含用户文件的大磁盘驱动器由系统初始化程序挂载,四个较小的磁盘驱动器可供用户挂载自己的磁盘包。通过在其相应的特殊文件上写入来生成可挂载的文件系统。可以使用实用程序来创建空文件系统,也可以简单地复制现有文件系统。

挂载的效果是使对之前普通文件的引用改为引用可移动卷上的文件系统的根目录。

对不同设备上的文件进行相同处理的规则只有一个例外:在一个文件系统层次结构和另一个文件系统层次结构之间不能存在任何链接。实施这一限制是为了避免复杂的簿记,否则,当可拆卸卷最终被卸下时,将需要进行详细的簿记以确保移除链节。具体地说,在所有文件系统的根目录中,无论是可移动的还是不可移动的,名称..。指的是目录本身,而不是其父目录。

尽管UNIX中的访问控制方案非常简单,但它有一些不寻常的特性。系统的每个用户都被分配了唯一的用户标识号。创建文件时,会使用其所有者的用户ID对其进行标记。还为新文件指定了一组七个保护位。其中六个为文件所有者和所有其他用户指定独立的读、写和执行权限。

如果第七位为ON,则每当文件作为程序执行时,系统都会将当前用户的用户标识临时更改为文件创建者的用户标识。用户ID中的此更改仅在调用它的程序执行期间有效。Set-User-ID功能提供特权程序,这些程序可能使用其他用户无法访问的文件。例如,程序可能保存一个会计文件,除了程序本身之外,该文件既不应该读取,也不应该更改。如果程序的SET-USER-IDENTIFICATION位为ON,则它可以访问该文件,尽管此访问可能禁止由给定程序的用户调用的其他程序。由于任何程序的调用者的实际用户ID总是可用的,因此设置用户ID的程序可以采取任何期望的措施来满足其调用者的凭证。此机制用于允许用户执行精心编写的调用特权系统条目的命令。例如,有一个只能由“超级用户”(如下所示)调用的系统条目,它创建了一个空目录。如上所述,目录应包含的条目。然后..。。创建目录的命令由超级用户所有,并且具有Set-User-ID位集。在检查其调用者创建指定目录的授权之后,它创建该目录并使

由于任何人都可以在自己的某个文件上设置Set-User-ID位,因此通常无需管理干预即可使用此机制。例如,该保护方案很容易解决[7]中提出的MoO会计问题。

系统将一个特定的用户ID(超级用户的ID)识别为免除了对文件访问的通常限制;因此(例如)可以编写程序来转储和重新加载文件系统,而不会受到来自保护系统的不想要的干扰。

用于执行I/O的系统调用旨在消除各种设备和访问方式之间的差异。“随机”I/O和顺序I/O之间没有区别,系统也没有强加任何逻辑记录大小。普通文件的大小由其上写入的最高字节决定;不需要或不可能预先确定文件的大小。

“随机”I/O和顺序I/O之间没有区别,系统也没有强加任何逻辑记录大小。

为了说明UNIX中I/O的本质,下面用匿名语言总结了一些基本调用,它将指示所需的参数,而不涉及机器语言编程的复杂性。每次对系统的调用都可能潜在地导致错误返回,为简单起见,调用序列中没有表示这一点。

要读取或写入假定已存在的文件,必须通过以下调用将其打开:

Name表示文件的名称。可以给出任意的路径名。Flag参数指示文件是否要被读取、写入或“更新”,即同时读取和写入。

返回值Filep称为文件描述符。它是一个小整数,用于在读取、写入或以其他方式操作文件的后续调用中标识该文件。

要创建新文件或完全重写旧文件,可以使用create system调用,如果给定文件不存在,则创建该文件;如果给定文件存在,则将其截断为零长度。CREATE还会打开新文件进行写入,并与OPEN一样返回文件描述符。

文件系统中没有用户可见的锁,也没有对打开文件以进行读或写的用户数量的任何限制;虽然当两个用户同时在文件上写入时,文件内容可能会变得混乱,但在实践中并不会出现困难。我们认为,在我们的环境中,锁既不是必要的,也不是充分的,以防止同一文件的用户之间的干扰。它们是不必要的,因为我们面对的不是由独立进程维护的大型单一文件数据库。它们是不够的,因为通常意义上的锁定(由此阻止一个用户在另一个用户正在读取的文件上写入)不能防止混淆,例如,当两个用户都在用制作正在编辑的文件的副本的编辑器编辑文件时。

应该说,当两个用户同时进行写入同一文件、在同一目录下创建文件或删除彼此打开的文件等不方便的活动时,系统具有足够的内部联锁来维护文件系统的逻辑一致性。

除非如下所示,读取和写入是顺序的。这意味着,如果文件中的特定字节是写入(或读取)的最后一个字节,则下一个I/O调用隐式引用后面的第一个字节。对于每个打开的文件,都有一个由系统维护的指针,指示要读取或写入的下一个字节。如果读取或写入n个字节,则指针前进n个字节。

在Filep指定的文件和Buffer指定的字节数组之间传输最多计数个字节。返回值n是实际传输的字节数。在写入情况下,n与COUNT相同,除非在特殊情况下,如I/O错误或特殊文件上的物理介质结束;但是,在读取时,n可能没有错误地小于COUNT。如果读取指针离文件末尾太近,以至于读取计数字符会导致读取超出末尾,则只会传输足够的字节到达文件末尾;而且,类似打字机的设备永远不会返回超过一行输入。当读取调用返回的n等于零时,它表示文件结束。对于磁盘文件,当读取指针变得等于文件的当前大小时会发生这种情况。可以通过使用转义序列从打字机生成文件结尾,该转义序列取决于所使用的设备。

写入文件的字节仅影响写指针位置和计数所暗示的字节;文件的其他部分不会更改。

.