diff --git a/UCB-CS162/L02-Fundatmental-OS-Concepts.md b/UCB-CS162/L02-Fundatmental-OS-Concepts.md index 999745c..a5e7b8a 100644 --- a/UCB-CS162/L02-Fundatmental-OS-Concepts.md +++ b/UCB-CS162/L02-Fundatmental-OS-Concepts.md @@ -8,4 +8,180 @@ - 复杂性会“泄露”出来。例如一些第三方驱动程序导致系统崩溃,或者某些功能无法正常工作。 - 安全漏洞。例如2017年,Intel的CPU存在一个名为Meltdown的漏洞。攻击者甚至可以访问kernel模式的内存! -- 不同版本的库会导致应用程序可能出问题。(现在我们有了Docker) \ No newline at end of file +- 不同版本的库会导致应用程序可能出问题。(现在我们有了Docker) + +一般来说,操作系统进行的"抽象"包括: + +- Processor -> Thread +- Memory -> Address Space +- Disks, SSDs, ... -> Files +- Networks -> Sockets +- Machines -> Processes + +## Thread of Control + +Thread 是一个独一无二的context, 其包括程序计数器、寄存器、堆栈、CPU标志位、内存等等。 + +### Resident / Running 驻留(运行态) + +当一个线程处于Resident状态时,表示该线程正在被CPU执行。 + +Resident指: 寄存器当前保存了该线程的state (content)。 + +- 包括程序计数器(PC, program counter)、当前执行的指令的地址 + - PC指向内存中下一条指令的地址 +- 包括程序当前正在计算的数据 +- 栈指针 +- 剩下的、内存里的数据 + +### Suspended / Ready 挂起(就绪态) + +当一个线程处于Suspended状态时,表示该线程已经准备好运行,但由于某些原因(如等待资源、等待I/O操作完成等)而暂时未执行。 + +与Resident状态具有很多相反的状态: + +- CPU的state不再是该线程的content,而是另一个线程的content +- PC指向另一个线程的指令地址 +- 大多数情况下,线程的content被保存在内存中,而不是寄存器中 + +### Content Switch 上下文切换 + +#### 使用场景 + +现代的操作系统通常支持多线程。电脑上可以同时运行很多线程,但单个CPU核心一次只能执行一个线程。当操作系统需要切换正在运行的线程时,就会发生上下文切换。 + +以图中为例: +![CPU上下文切换](/UCB-CS162/images/L02-content-switch.png) + +- T1时刻,vCPU1在CPU核心上,vCPU2在内存中 +- T2时刻,vCPU1在内存中,vCPU2在CPU核心上 + +在T1和T2之间,操作系统进行了一次**context switch**,也就是上下文切换: + +- 将vCPU1的状态保存到**Thread Control Block** (TCB, 位于内存) 中。 +- 将vCPU2的状态从内存加载到CPU核心上 +- 其他操作..... + +上下文切换不是毫无开销的。一般来讲,它会耗费几微秒的时间。因此,操作系统会尽量减少上下文切换的次数,并使用各种手段减少上下文切换的开销,以提高系统性能。 + +有多种条件可以出发一次Content Switch: 计时器、I/O事件、系统调用、线程优先级变化等等。 + +#### Thread Control Block (TCB) + +TCB是一些数据,保存了线程的状态信息,包括寄存器值、堆栈指针、程序计数器、PC等。 + +通常来讲,TCB被存储在内存的kernel空间中。 + +#### Address Space 地址空间 + +![简化的地址空间](/UCB-CS162/images/L02-Simplified-Address-Space.png) + +## Reliability 可靠性 + +简单的上下文切换不提供操作系统保护,而我们显然不会希望一个user program崩掉整个系统!因此,操作系统需要提供一些保护机制。 + +- 可靠性:破坏操作系统通常会导致其崩溃 +- 安全性:限制线程的操作范围 +- 隐私性:限制每个线程仅能访问其被允许访问的数据 +- 公平性:每个线程应限制在其应得的系统资源份额内(CPU时间、内存、I/O等) + +仅靠软件是不足以更好的保护系统的,因此我们有了一些硬件层面的保护机制: + +### Base and Bound (B&B) 基址寄存器、边界寄存器 + +![Base & Bound image](/UCB-CS162/images/L02-Base-and-Bound.png) +如图所示,程序地址“看起来”位于 0 ~ 100 之间;但,当它被加载到内存内时,它被重新定位到 1000 ~ 1100 之间。 + +这是一种基于编译器、加载器的保护机制。它把操作系统和用户程序隔离,保护操作系统。 + +我们也可以通过添加一个加法器来实现更高效的B&B机制: +![B&B Hardware Assistant 1](/UCB-CS162/images/L02-B&B-Hardware-Assistant-1.png) +这是一种硬件辅助的内存重定向。 + +B&B机制有很多缺点。最显著的缺点之一是,它无法简单地处理用户程序allocate或者free内存的情况。由此,我们有了一个更复杂的机制: + +### Address Space Translation 地址空间转换 + +我们可以通过增添一个特定的“小盒子”,来实现更高效的地址空间转换: +![Address Space Translation](/UCB-CS162/images/L02-Address-Space-Translation-Overview.png) +这个“小盒子”被称为**Memory Management Unit** (MMU),它可以将虚拟地址转换为物理地址。 + +这个解决方案很好地解决了B&B机制的缺点。用户程序可以allocate或者free内存,而不需要担心地址空间的重叠问题。其中,有一个至今仍然在使用的机制: **Paging** (分页机制)。 + +### Paging 分页机制 + +分页机制将内存划分为固定大小的页(通常是4KB)。每个页都有一个对应的页表项,记录了该页在物理内存中的位置。当程序访问一个虚拟地址时,MMU会查找对应的页表项,将虚拟地址转换为物理地址。 +![Paged Memory](/UCB-CS162/images/L02-Paged-Memory.png) + +我们还可以实现一点更“酷”的东西。为了节约内存,我们甚至可以让一些Page实际上不在内存中!对这些page的访问会触发一个**page fault**,程序中断后,操作系统将所需的page从磁盘加载到内存中,然后继续执行程序。 + +## Processes 进程 + +进程是具有受限权限的执行环境。 + +- (受保护的)具有一个或多个线程的地址空间 +- 拥有内存(地址空间) +- 拥有文件描述符、文件系统上下文... +- 封装一个或多个共享进程资源的线程 + +复杂的应用程序可以 fork/exec(创建/执行)子进程。 + +某种意义上来说,进程是一些“城市”,而操作系统是管理他们的“政府”。 + +- 每个城市都有自己的居民(线程),有自己的资源(内存、文件描述符等)。程序假设它们是独立的,不会相互干扰。 +- 政府负责管理这些城市,确保城市A出问题不会波及到城市B、审查城市AB之间的通信、分配硬件资源给城市, etc. + +### 为什么需要进程? + +- 它让不同程序、组件之间相互隔离,不会一个崩溃连带其他崩溃。 +- 操作系统免受它们的影响 +- 提供内存保护 + +### 保护与效率之间的基本权衡 + +- 进程**内**通信更容易。 + - 线程之间可以直接访问共享内存 +- 进程**间**通信更难 + - 需要使用IPC机制(如管道、消息队列、共享内存等)来进行通信 + +### 单线程与多线程 + +![Single Thread vs Multi Thread](/UCB-CS162/images/L02-Single-Thread-vs-Multi-Thread.png) +可以从途中看到,各个线程**共享资源**(同一个地址空间、文件描述符等),但每个线程都有**自己的程序计数器、寄存器、堆栈**等。 + +## privilege levels 权限级别 + +上边我们提到了页表。那如果,应用A想要把页的映射地址改到一个它不应该访问的地址上怎么办?我们有了权限级别来解决这个问题。 + +### Dual Mode Operation 双模式操作 + +CPU至少会提供以下两个模式: + +- User mode (Ring 3) 用户模式:应用程序运行在这个模式下,权限受限,无法直接访问硬件资源。 +- Kernel mode (Ring 0) 内核模式:操作系统运行在这个模式下,拥有完全的权限。 + +由此,我们解决了问题:当操作系统让其他应用程序运行时,它会将CPU切换到User mode。这样子,应用A就不能直接修改页表了。 + +如果应用程序需要从硬盘读取数据,它会发出一个系统调用(system call),请求操作系统执行这个操作。操作系统会将CPU切换到Kernel mode,执行相应的操作,然后再切换回User mode。 + +由此,我们得出了经典的UNIX系统架构: +![Simplified Unix System Architecture](/UCB-CS162/images/L02-Simplified-Unix-System-Architecture.png) + +### How to switch? 如何切换当前模式? + +从用户态到内核态: + +- ```System call``` 系统调用 + - 定义: 进程请求系统服务,例如exit + - 系统调用类似于函数调用 + - 没有要调用的系统函数的地址 + - 类似于远程过程调用 (RPC) + - 将系统调用 ID 和参数整理到寄存器中,并执行系统调用 +- ```Interrupt``` 中断 + - 某些原因触发上下文切换 + - 例如:Timer 、I/O 设备 +- ```Trap``` 陷阱或```Exception``` 异常 + - 进程内部同步事件触发上下文切换 + - 例如:```Protection Violation - Segmentation Fault```(段错误)、除以零, etc. + +在一次,例如```Interrupt```发生后,CPU会把当前正在运行的程序保存在```Thread Control Block (TCB)```中。TCB中保存了程序计数器、寄存器值、堆栈指针等,并存储在Kernal memory中。 \ No newline at end of file diff --git a/UCB-CS162/images/L02-Address-Space-Translation-Overview.png b/UCB-CS162/images/L02-Address-Space-Translation-Overview.png new file mode 100644 index 0000000..13e6b04 Binary files /dev/null and b/UCB-CS162/images/L02-Address-Space-Translation-Overview.png differ diff --git a/UCB-CS162/images/L02-B&B-Hardware-Assistant-1.png b/UCB-CS162/images/L02-B&B-Hardware-Assistant-1.png new file mode 100644 index 0000000..87d8b7c Binary files /dev/null and b/UCB-CS162/images/L02-B&B-Hardware-Assistant-1.png differ diff --git a/UCB-CS162/images/L02-Base-and-Bound.png b/UCB-CS162/images/L02-Base-and-Bound.png new file mode 100644 index 0000000..8e37b9b Binary files /dev/null and b/UCB-CS162/images/L02-Base-and-Bound.png differ diff --git a/UCB-CS162/images/L02-Paged-Memory.png b/UCB-CS162/images/L02-Paged-Memory.png new file mode 100644 index 0000000..a4bc170 Binary files /dev/null and b/UCB-CS162/images/L02-Paged-Memory.png differ diff --git a/UCB-CS162/images/L02-Simplified-Address-Space.png b/UCB-CS162/images/L02-Simplified-Address-Space.png new file mode 100644 index 0000000..79883b3 Binary files /dev/null and b/UCB-CS162/images/L02-Simplified-Address-Space.png differ diff --git a/UCB-CS162/images/L02-Simplified-Unix-System-Architecture.png b/UCB-CS162/images/L02-Simplified-Unix-System-Architecture.png new file mode 100644 index 0000000..b29c01d Binary files /dev/null and b/UCB-CS162/images/L02-Simplified-Unix-System-Architecture.png differ diff --git a/UCB-CS162/images/L02-Single-Thread-vs-Multi-Thread.png b/UCB-CS162/images/L02-Single-Thread-vs-Multi-Thread.png new file mode 100644 index 0000000..2706d85 Binary files /dev/null and b/UCB-CS162/images/L02-Single-Thread-vs-Multi-Thread.png differ diff --git a/UCB-CS162/images/L02-content-switch.png b/UCB-CS162/images/L02-content-switch.png new file mode 100644 index 0000000..819cfd9 Binary files /dev/null and b/UCB-CS162/images/L02-content-switch.png differ