第一章 引论
1.什么是操作系统
1.1作为扩展的机器的操作系统(硬盘为例来解释)
在机器语言一级上,计算机体系结构(指令集,存储系统,io和总线结构)很原始,编程起来很困难。之前使用驱动程序软件来和硬件进行交互,但是对于大多数应用来说还是太底层,于是提供了使用硬盘的有一层细节:文件,使用该抽象,程序能创建,读写文件。
好的将一个几乎不可能管理的任务划分为两个可管理的部分,一是抽象的定义和实现,二是用这些抽象解决问题。操作系统的任务是创建好的抽象并实现和管理它所创建的抽象对象。
1.2作为系统资源的管理者
自顶向下的观点:把操作系统看作是向应用程序提供基本抽象的概念
自底向上的观点:操作系统则用来管理一个复杂系统的各个部分,在相互竞争的程序之间有序地控制对处理器、存储器以及其他I/O接口设备的分配。
当一个计算机(或网络)有多个用户时,操作系统的主要任务是记录哪个程序在使用什么资源,对资源请求进行分配,评估使用代价,并且为不同的程序和用户调解互相冲突的资源请求。
资源管理包括用以下两种不同方式实现多路复用(共享)资源:在时间上复用和在空间上复用。
时间复用:不同的程序或用户轮流使用它。先是第一个获得资源的使用,然后下一个,以此类推。
空间复用:
通常在若干运行程序之间分割内存,这样每一个运行程序都可同时入住内存。
一个磁盘同时为许多用户保存文件。分配磁盘空间并记录谁正在使用哪个磁盘块,是操作系统资源管理的典型任务。
2.操作系统的历史
2.1第一台真正的计算机(纯机械机构)
第一台真正的数字计算机是英国数学家Charles Babbage(1792-1871)设计的。但是他始终未能让机器正常的运转,因为它是一台纯机械的数字计算机,他所在时代的技术不能生产出他所需要的高精度轮子、齿轮和轮牙。
Babbage认识到他的分析机需要软件,所以他雇佣了一个名为Ada Lovelace的年轻妇女,作为世界上第一个程序员,而她是著名的英国诗人Lord Byron的女儿。程序设计语言Ada则是以她命名的。
2.2第一代(1945~1955):真空管和穿孔卡片
使用机器的一般方式是,程序员在墙上的机时表上预约一段时间,然后到机房中将他的插件板接到计算机里,在接下来的几小时里,期盼正在运行中的两万多个真空管不会烧坏。那时,所有的计算问题实际都只是简单的数字运算,如制作正弦、余弦以及对数表等。
到了20世纪50年代早期有了改进,出现了穿孔卡片,这时就可以将程序写在卡片上,然后读入计算机而30不用插件板,但其他过程则依然如旧。
2.3第二代(1955~1965):晶体管和批处理系统
锁在有专用空调的房间中,由专业操作人员运行。要运行一个作业(job,即一个或一组程序),程序员首先将程序写在纸上(用FORTRAN语言或汇编语言),然后穿孔成卡片,再将卡片盒带到输入室,交给操作员,接着就喝咖啡直到输出完成。
计算机运行完当前的任务后,其计算结果从打印机上输出,操作员到打印机上撕下运算结果并送到输出室,程序员稍后就可取到结果。然后,操作员从已送到输入室的卡片盒中读入另一个任务。如果需要FORTRAN编译器,操作员还要从文件柜把它取来读入计算机。当操作员在机房里走来走去时许多机时被浪费掉了。
批处理系统(batch system):在输入室收集全部的作业,然后用一台相对便宜的计算机,如IBM 1401计算机,将它们读到磁带上。IBM 1401计算机适用于读卡片、复制磁带和输出打印,但不适用于数值运算。另外用较昂贵的计算机,如IBM 7094来完成真正的计算。
2.4第三代(1965~1980):集成电路芯片和多道程序设计
对于CPU操作密集的科学计算问题,I/O操作较少,因此浪费的时间很少。然而,对于商业数据处理,I/O操作等待的时间通常占到80%~90%,所以必须采取某种措施减少(昂贵的)CPU空闲时间的浪费。
将内存分几个部分,每一部分存放不同的作业,如图1-5所示。当一个作业等待I/O操作完成时,另一个作业可以使用CPU。如果内存中可以同时存放足够多的作业,则CPU利用率可以接近100%。在内存中同时驻留多个作业需要特殊的硬件来对其进行保护,以避免作业的信息被窃取或受到攻击。
第三代计算机的另一个特性是,卡片被拿到机房后能够很快地将作业从卡片读入磁盘。于是,任何时刻当一个作业运行结束时,操作系统就能将一个新作业从磁盘读出,装进空出来的内存区域运行。这种技术叫做同时的外部设备联机操作(Simultaneous Peripheral Operation On Line,SPOOLing),该技术同时也用于输出。当采用了SPOOLing技术后,就不再需要IBM 1401机,也不必再将磁带搬来搬去了。
缺点
第三代操作系统很适于大型科学计算和繁忙的商务数据处理,但其实质上仍旧是批处理系统。许多程序员很怀念第一代计算机的使用方式。那时,他们可以几个小时地独占一台机器,可以即时地调试他们的程序。而对第三代计算机而言,从一个作业提交到运算结果取回往往长达数小时,更有甚者,一个逗号的误用就会导致编译失败,而可能浪费了程序员半天的时间。
于是导致了分时系统MULTICS的出现。(一种“公用计算服务系统”,能够同时支持数百名分时用户的一种机器。)
计算服务的思想:云计算,相对小型的计算机连接到巨大的远程数据中心服务器。
2.5第四代(1980年至今):个人计算机
2.6 第五代(1990至今):移动计算机
3.计算机硬件简介
3.1处理器
多数计算机还有一些对程序员可见的专门寄存器。其中之一是程序计数器,它保存了将要取出的下一条指令的内存地址。
另一个寄存器是堆栈指针,它指向内存中当前栈的顶端。该栈含有已经进入但是还没有退出的每个过程的一个框架。在一个过程的堆栈框架中保存了有关的输入参数、局部变量以及那些没有保存在寄存器中的临时变量。
程序状态字(Program Status Word,PSW)寄存器。这个寄存器包含了条件码位(由比较指令设置)、CPU优先级、模式(用户态或内核态),以及各种其他控制位。用户程序通常读入整个PSW,但是,只对其中的少量字段写入。
为了改善性能,提出了流水线(pipeline)机制
比流水线更先进的设计是一种超标量CPU,有多个执行单元
这种设计存在一种隐含的作用,即程序的指令经常不按顺序执行。
3.2存储器
缓存在计算机科学的许多领域中起着重要的作用,并不仅仅只是RAM的缓存行。
类似于/home/ast/projects/minix3/src/kernel/clock.c的长路径名转换成文件所在的磁盘地址的结果,也可以放入缓存,以避免重复寻找地址。还有,当一个Web页面(URL)的地址转换为网络地址(IP地址)后,这个转换结果也可以缓存起来以供将来使用。
只读存储器(Read Only Memory,ROM)在工厂中就被编程完毕,然后再也不能被修改。ROM速度快且便宜。在有些计算机中,用于启动计算机的引导加载模块就存放在ROM中。
是CMOS,它是易失性的。许多计算机利用CMOS存储器保持当前时间和日期。CMOS存储器和递增时间的时钟电路由一块小电池驱动,所以,即使计算机没有上电,时间也仍然可以正确地更新。CMOS存储器还可以保存配置参数,诸如,哪一个是启动磁盘等。之所以采用CMOS是因为它消耗的电能非常少,一块工厂原装的电池往往就能使用若干年。
3.3磁盘
计算机支持一种著名的虚拟内存机制。这种机制使得期望运行大于物理内存的程序成为可能,其方法是将程序放在磁盘上,而将主存作为一种缓存,用来保存最频繁使用的部分程序。这种机制需要快速地映像内存地址,以便把程序生成的地址转换为有关字节在RAM中的物理地址。
3.4I/O设备
为了能够使用设备驱动程序,必须把设备驱动程序装入到操作系统中,这样它可在核心态中运行。
要将设备驱动程序装入操作系统,有三个途径。
第一个途径是将内核与设备驱动程序重新链接,然后重启动系统。许多UNIX系统以这种方式工作。
第二个途径是在一个操作系统文件中设置一个入口,并通知该文件需要一个设备驱动程序,然后重启动系统。在系统启动时,操作系统去找寻所需的设备驱动程序并装载之。Windows就是以这种方式工作。
第三种途径是,操作系统能够在运行时接受新的设备驱动程序并且立即将其安装好,无须重启动系统。这种方式采用的较少,但是这种方式正在变得普及起来。热插拔设备,诸如USB和IEEE1394设备都需要动态可装载设备驱动程序。
3.5总线
通用串行总线(Universal Serial Bus,USB)是用来将所有慢速I/O设备,诸如键盘和鼠标,与计算机连接。
SCSI(Small Computer System Interface)总线是一种高速总线,用在高速硬盘、扫描仪和其他需要较大带宽的设备上。它最高可达320MB/s。
3.6启动计算机
在每个Pentium上有一块双亲板(在政治上的纠正影响到计算机产业之
前,它们曾称为“母板”)。在双亲板上有一个称为基本输入输出系统(Basic Input Output System,BIOS)的程序。在BIOS内有底层I/O软件,包括读键盘、写屏幕、进行磁盘I/O以及其他过程。现在这个程序存放在一块闪速RAM中,它是非可易失性的,但是在发现BIOS中有错时可以通过操作系统对它进行更新。
在计算机启动时,BIOS开始运行。它首先检查所安装的RAM数量,键盘和其他基本设备是否已安装并正常响应。接着,它开始扫描ISA和PCI总线并找出连在上面的所有设备。其中有些设备是典型的遗留设备(即在即插即用发明之前设计的),并且有固定的中断级别和I/O地址(也许能用在I/O卡上的开关和跳接器设置,但是不能被操作系统修改)。这些设备被记录下来。即插即用设备也被记录下来。如果现有的设备和系统上一次启动时的设备不同,则配置新的设备。
然后,BIOS通过尝试存储在CMOS存储器中的设备清单决定启动设备。用户可以在系统刚启动之后进入一个BIOS配置程序,对设备清单进行修改。典型地,如果存在软盘,则系统试图从软盘启动。如果失败则试用CD-ROM,看看是否有可启动CD-ROM存在。如果软盘和CD-ROM都没有,系统从硬盘启动。启动设备上的第一个扇区被读入内存并执行。这个扇面中包含一个对保存在启动扇面末尾的分区表检查的程序,以确定哪个分区是活动的。然后,从该分区读入第二个启动装载模块。来自活动分区的这个装载模块被读入操作系统,并启动之。
然后,操作系统询问BIOS,以获得配置信息。对于每种设备,系统检查对应的设备驱动程序是否存在。如果没有,系统要求用户插入含有该设备驱动程序的CD-ROM(由设备供应商提供)。一旦有了全部的设备驱动程序,操作系统就将它们调入内核。然后初始化有关表格,创建需要的任何背景进程,并在每个终端上启动登录程序或GUI。