MIT 6.828
课程目标
- 理解操作系统的设计和实现
- 通过一个小的叫做XV6的操作系统,获得实际动手经验
操作系统的共同目标
- 抽象硬件:提供高级的接口和抽象,例如进程,文件系统,这些高层级的接口和抽象(Abstraction)方便了应用的开发,也提供了更好的移植性
- 在多个应用程序之间共用硬件资源,互不干扰,在需要的时候实现共享,在没有必要的时候不共享(权限)
- 需要至少不阻止应用程序获得高性能
- 能够支持大量不同的用户场景
操作系统结构
操作系统经典的组织结构
- 硬件资源包括了CPU,内存,磁盘,网卡
- 程序都运行在同一个空间中,这个空间通常会被称为用户空间
- 区别于用户空间程序,有一个特殊的程序总是会在运行,它称为Kernel
- Kernel是计算机资源的守护者。当你打开计算机时,Kernel总是第一个被启动。
- Kernel程序只有一个,它维护数据来管理每一个用户空间进程
- Kernel同时还维护了大量的数据结构来帮助它管理各种各样的硬件资源,以供用户空间的程序使用
- Kernel同时还有大量内置的服务,例如,Kernel通常会有文件系统实现类似文件名,文件内容,目录的东西
在这门课程中,我们主要关注点在Kernel、连接Kernal和用户空间程序的接口、Kernel内软件的架构。所以,我们会关心Kernel中的服务,其中一个服务是文件系统,另一个就是进程管理系统
进程管理系统
每一个用户空间程序都被称为一个进程,它们有自己的内存和共享的CPU时间。
同时,Kernel会管理内存的分配。不同的进程需要不同数量的内存,Kernel会复用内存、划分内存,并为所有的进程分配内存。
文件系统
文件系统通常有一些逻辑分区。目前而言,我们可以认为文件系统的作用是管理文件内容并找出文件具体在磁盘中的哪个位置。文件系统还维护了一个独立的命名空间,其中每个文件都有文件名,并且命名空间中有一个层级的目录,每个目录包含了一些文件。所有这些都被文件系统所管理
Access Control机制
这里还有一些安全的考虑,我们可以称之为Access Control,它决定了哪些进程可以访问哪些文件。
更多
在一个真实的完备的操作系统中,会有很多很多其他的服务,比如在不同进程之间通信的进程间通信服务,比如一大票与网络关联的软件(TCP/IP协议栈),比如支持声卡的软件,比如支持数百种不同磁盘,不同网卡的驱动。所以在一个完备的系统中,Kernel会包含大量的内容,数百万行代码
系统调用
系统调用与程序中的函数调用看起来是一样的,但区别是系统调用会实际运行到系统内核中,并执行内核中对于系统调用的实现。
这里先介绍一些简单的系统调用,后续会详细的展开
open
如果应用程序需要打开一个文件,它会调用名为open的系统调用,并且把文件名作为参数传给open。假设现在要打开一个名为“out”的文件,那么会将文件名“out”作为参数传入。同时我们还希望写入数据,那么还会有一个额外的参数,在这里这个参数的值是1,表明我想要写文件
fd=open("out",1);
write
如果应用程序想要写入数据,它会调用名为write的系统调用,并且把文件描述符和要写数量传入
fd=open("out",1);
char[] data="Hello World";
write(fd,data,sizeof(data));
fork
fork是一个这样的系统调用,它创建了一个与调用进程一模一样的新的进程,并返回新进程的process ID/pid。这里实际上会复杂的多,我们后面会有更多的介绍。
fd=open("out",1);
char[] data="Hello World";
write(fd,data,sizeof(data));
pid=fork();