MIT 6.S081课程笔记0——关于课程
该笔记主要记录的是实验以外的学习笔记包括一些自己的想法以及不理解地方的查阅,如有不正确的地方,欢迎指出!
课程目标
- 设计和实现操作系统
- 在小型操作系统xv6上的实操
- 聚焦在【内核】以及【内核与用户程序】之间的接口
操作系统目标
- 对硬件的抽象
- 多个硬件在多个应用中使用
- 隔离性:许多应用同时运行,如何保证它们之间不会相互干扰,即使它们可能存在bug
- 共享性:一些应用需要进行协作
- 安全性:
- 需要一些控制访问
- 例子:Athena(时分复用的操作系统),不希望其他用户访问你的文件
- 性能:一些硬件费用非常昂贵,因此希望可以达到更好的性能
- 用途广泛:设计和实现操作系统都是非常昂贵的,因此操作系统应该尽量提供非常广泛的用途
操作系统内部组织架构
架构描述:
- 顶层是用户空间USER SPACE,底层是cpu、ram、disk、network
缩写解释:
- vi:text editor
- cc:c compiler
- sh:shell command line interface
- FS:file system
名词解释:
- Process:进程,运行中的程序,拥有独立的内存空间以及共享cpu时间片
- Mem Alloc:内核管理内存的分配
- Access CTL:访问控制
系统调用
类似方法调用,发生系统调用的时候,处理器会切换到内核态,内核完成系统调用请求。
例如,打开文件的时候,会调用【文件打开】系统调用,并且传参告知【文件打开】系统调用需要打开的文件名。内核获取到参数,并且执行实现文件打开的内核代码。
// fd:file descriptor:指向要打开的文件的句柄
// 通常,0指的是输入控制台
// 1指的是输出控制台,这个之后在输出重定向的时候会仔细分析
// "out"是打开的文件名,1是操作类型(以什么方式打开),这里指的是只写的方式打开
fd = open("out", 1);
// fd:即将写入的文件描述符
// "hello\n"与6组合:从这个字符串指向的地址读取6个bytes到fd对应的文件
write(fd, "hello\n", 6);
系统调用 vs. 函数调用
机器让内核有特权,使得内核可以直接操作如磁盘等各种各样的硬件,然而普通用户编程者不能直接操作。内核可以修改各种各样的敏感、受保护的硬件资源。
系统调用 vs. 高级语言
关系
- 高级语言(如Python)通常不会直接暴露底层的系统调用接口。
- 高级语言更多是通过内置函数或包装器(wrappers)来间接调用系统调用,从而提供更简洁和跨平台的接口。
为什么要间接包装?
- 很多高级语言系统提供可移植性(portable),即能在不同的操作系统上运行。
- 如果直接绑定某个操作系统的系统调用,就失去了跨平台的优势。
Python的系统调用情况
- Python内部其实还是需要依赖系统调用来完成具体工作。
- 但是Python提供了一层抽象,让用户在多数情况下不需要直接和系统调用打交道。
- 在某些场景下,Python也允许用户直接使用系统调用接口(比如通过os模块)
为什么困难与有趣?
- 内核内部的程序环境是无情的(unforgiving)
- 当修改、扩展内核或者写一个新的操作系统内核,我们做的是基础设施infrastructure的工作
- 写普通应用程序的时候,有现成的操作系统可依赖;写操作系统的时候,依赖的是底层硬件,在课程中用的是QEMU模拟CPU和Memory。
- 需要真正的设计思维
- 高效:靠近硬件。并且易用:意味着要提供高度抽象的接口,便于人们写程序的时候使用。
- 强大(可以处理不同种类的任务)且简单的api。
- 灵活和安全
- 自由,但不是绝对的自由,需要保证一个程序不会影响另外一个程序,不会影响操作系统本身的运行。
- 交互:一个父进程创建的子进程,该子进程会拷贝当前进程。如果父进程打开了一个文件,这个打开的文件的文件描述符也会被该子进程共享。
说明
XV6运行在一个RISC-V微处理器上,而RISC-V是MIT6.001课程讲解的处理器。