从自顶向下的观点来看,把操作系统看作向应用程序提供基础抽象。在机器语言一级上,多数计算机的体系结构是很难编程的,尤其是输入输出而言。以硬盘为例,早期硬盘接口复杂难以编程,而操作系统提供使用硬盘的抽象–文件。使用该抽象,程序能创建、读写文件,而不用直接处理硬件。
抽象是管理复杂性的一个关键。好的抽象可以吧一个几乎不可能管理的任务划分称两个可管理得部分。一部分是有关抽象的定义和实现,第二部分使用这些抽象解决问题。
按照自底向上的观点,操作系统用来管理一个复杂系统的各个部分。现代计算机包括处理器、存储器、时钟、磁盘、网络接口、打印机以及其他设备。从这种观点看,操作系统的任务是在相互竞争的程序游学控制处理器,存储器,以及其他I/O设备的分配。
从多用户观点来看,操作系统的主要任务是记录程序需要那个资源,对资源请求分配,评估使用代价,为不同用户调节相互冲突的资源请求。
资源管理包括以下两种不同方式实现多路复用资源:在空间和时间上复用。时间复用,不同程序或用户轮流使用它,例如时间轮转。空间复用,每个程序获得资源的一部分,比如在若干程序之间分割内存。
进程本质上是正在执行的一个程序,与每个程序相关的是地址空间,这是从最小值的存储位置到某个最大值的存储位置的列表。地址空间存放有可执行程序,程序的数据以及程序的堆栈。与每个进程相关的还有进程表,通常包括寄存器,打开文件的清单、突出的报警、有关进程清单,以及运行程序所有其他信息。
与进程管理有关的最关键的系统调用是进程创建和终止的系统调用,若一个进程可以创建一个或多个进程,而这些进程又可以创建子进程,则很容易得到进程树。
其他可用的进程系统调用包括:申请更多的内存,等待一个子进程结束等
系统管理器授权每个进程一个UID,每个程序都有启动该进程的用户UID,子进程和父进程一样的UID。在UNIX有超级用户,或Windows的管理员有着特殊权力,可以做一些违背保护规则的事。
在内存同时运行多道程序,为了避免相互干扰,需要某种保护机制,机制是硬件的单由操作系统掌控。为了未来解决一个进程比主存还大的地址空间,有了虚拟内存的概念。操作系统创建了一个地址空间的抽象,作为进程可以引用地址的集合。
为了提供保存文件的地方,提出了目录的概念,目录项可以是文件或者是目录,这样就产生了层次结构-文件系统。进程和文件层次都可以组织成树状结构,但文件系统的树往往更深,同时只有父进程能控制访问进程,而在文件和目录可以使所有者的其他用户也可以访问文件。
特殊文件,提供特殊文件是为了I/O设备看起来像文件一般。这样使用系统调用读写文件一样,I/O设备也可以通过同样的系统调用进行读写。有两类特殊文件:块特殊文件(磁盘)和字特殊文件(键盘)
管道是一种虚文件,它连接两个进程,如果进程A和进程B希望通过管道对话,它们必须设置管道。当进程A相对进程B发送数据时,他把数据写到管道上,进程B通过管道读取数据。
每个操作系统都有管理其I/O设备的I/O子系统,某些I/O设备独立的,I/O
软件的其他部分,如设备驱动程序是专门为特定的I/O设备设计的
操作系统具有两种功能:为用户程序提供抽象和管理计算机资源。在多数情况下用户和操作系统之间的交互是前者。对于用户而言资源主要是透明和自动完成的。为了了解操作系统,我们应该分析这个接口。
以c语言的read函数为例
这部分强烈建议看书,真的很好。这里仅介绍trap指令,trap指令执行后切换到内核态且不能跳转到任意地址上,或者跳转到单一固定地址,或者内存中的索引表。
fork():用于创建一个进程,所创建的进程复制父进程的代码段/数据段/BSS段/堆/栈等所有用户空间信息;在内核中操作系统重新为其申请了一个PCB,并使用父进程的PCB进行初始化;在父进程中,fork返回新创建进程的进程ID;在子进程中,fork返回0;如果出现错误,fork返回一个负值;
waitpid():如果在调用waitpid()函数时,当指定等待的子进程已经停止运行或结束了,则waitpid()会立即返回;但是如果子进程还没有停止运行或结束,则调用waitpid()函数的父进程则会被阻塞,暂停运行。
exceve():execve() 系统调用的作用是运行另外一个指定的程序。它会把新程序加载到当前进程的内存空间内,当前的进程会被丢弃,它的堆、栈和所有的段数据都会被新进程相应的部分代替,然后会从新程序的初始化代码和 main 函数开始运行。同时,进程的 ID 将保持不变。
lseek(): lseek(int fd, off_t offset, int whence);
fd:文件描述符,offset:偏移字节数,whence:文件指针所在位置SEEK_SET:起始位置、SEEK_CUR:当前位置、SEEK_END:末尾地址)
link(),是同一个文件以两个或多个名称出现,多数情况下在不同的目录中这样做,共享此文件。每个文件都有一个唯一的数字 - i-节点(i-node)号来标识它。i-节点号是i-节点表的索引值,每个文件有一个i-节点,里面存放有文件主以及该文件所占用的磁盘块等信息。目录实际上也是文件,只是其内容存放的是一些i-节点和文件名的对应信息。LINK所做的只是创建一个新的目录项,它有一个新文件名,但i-节点号则是被链接的文件的i-节点号。
mount(),MOUNT系统调用可将两个文件系统合并成一个。通常情况是先有一个存在于RAM盘上的根文件系统,其中包含有常用命令的可执行文件及其他常用文件。然后用户可以在驱动器0中插入一张存有用户程序的软盘。使用MOUNT系统调用就可以将软盘上的文件系统安装到根文件系统下。