CS162笔记第二章(操作系统)
一、课程开篇:回顾上一讲核心
上一讲我们讲了操作系统的三大角色:
裁判(Referee)
管理资源、保护、隔离、权限,不让进程互相干扰。
幻术师(Illusionist)
把丑陋硬件变成干净、易用的虚拟资源(线程、地址空间、文件等)。
粘合剂(Glue)
提供统一服务(窗口、文件系统、网络),让写程序更简单。
老师强调:
同一个物理硬件上,可以同时运行多个进程,每个进程都以为自己独占整台机器。
进程之间禁止互相访问 / 修改对方状态,也不能非法修改操作系统或存储。
一旦违规 → 操作系统直接终止进程 → 段错误(segmentation fault)。
二、硬件为什么极度复杂?
老师用 Skylake 处理器架构 举例:
- CPU 直连高带宽 DRAM、高速显卡
- 通过 DMI 接口连接 PCH 芯片组(原南桥)
- 下面挂着:PCIe 高速设备、磁盘、USB、网口、音频、raid 等
- 再下层还有更低速的设备
结论:
硬件极其杂乱、多样、复杂 → 必须由操作系统来管理与抽象。
三、系统复杂度的直观体现:代码行数
Linux 从 2.2 到 3.1,代码量增长 6 倍以上
现代汽车:约 1 亿行代码
设备驱动(第三方开发)是
BUG 重灾区
统计:超过
50%~60% 的系统崩溃来自驱动程序
安全漏洞:Spectre、Meltdown(投机执行导致内核数据泄露)
老师核心观点:
操作系统的根本意义:抽象硬件、驯服复杂度。
四、操作系统如何 “化繁为简”?(核心抽象)
硬件太烂 → OS 换成更好用的虚拟概念:
- 物理 CPU → 线程(Thread)
- 物理内存(零散 DRAM)→ 地址空间(Address Space)
- 磁盘 / SSD 裸数据块 → 文件系统(File System)
- 原始网络包 → Socket 接口
- 裸机 → 进程(Process)
五、本节课正式内容:操作系统 四大基本概念(必考)
老师明确:今天讲 4 个 OS 最基础概念,全程围绕它们展开。
概念一:线程(Thread)— 执行流
1. 线程是什么?
线程 = 一个独立的执行上下文(execution context)
包含:
- 程序计数器(PC)
- 寄存器集合
- 执行标志(flags)
- 栈(stack)
- 相关内存状态
2. 线程 = 虚拟化的 CPU(核心)
你在 61C 学的是物理 CPU 的取指执行。
OS 把它虚拟化 → 变成线程。
3. 常驻(resident)是什么意思?
当线程的 上下文在 CPU 寄存器里,它就是正在运行、常驻的。
一个核(core)同一时刻只能有一个线程常驻。
4. 线程挂起(suspended)
- 上下文不在寄存器里
- 被保存到内存中的 TCB(Thread Control Block,线程控制块)
- 程序计数器不再指向它
5. 多线程 “并发” 幻觉怎么实现?
单 CPU = 时分多路复用(time multiplexing)
- 运行线程 A 一小会儿
- 切换
- 运行线程 B 一小会儿
- 切换
- 运行线程 C…
因为切换极快 → 人感觉 “同时运行”。
6. 上下文切换(context switch)做什么?
- 把当前线程所有寄存器、PC、栈指针保存到内存 TCB
- 加载下一个线程的上下文到 CPU
- 开始执行新线程
切换耗时:几微秒
不能切换太快,否则大部分时间都在切换(颠簸 /thrashing)。
概念二:地址空间(Address Space)
1. 定义
地址空间 = 程序可访问的所有地址集合 + 对应状态
例:32 位地址空间
0 ~ 0xFFFFFFFF(约 4GB)
2. 地址空间内部布局
- 代码段(text/code):指令
- 静态数据段(data):全局变量、静态变量、字符串常量
- 栈(stack):局部变量、函数调用
- 堆(heap):malloc 分配的内存
3. 早期简单保护:基址 + 界限(Base + Bound)
最早的硬件保护方案:
- 两个寄存器:基址、界限
- 程序只能访问
[base, bound]之间的内存 - 访问越界 → 直接报错
优点:简单、硬件成本低
缺点:扩展麻烦、会产生内存碎片
4. 进阶:地址翻译(虚拟内存)
后面课程重点:
把程序使用的 虚拟地址 → 页表翻译 → 物理地址
- 无碎片
- 可以离散存放
- 可以置换到磁盘
- 可以隔离保护
概念三:进程(Process)— 本讲最重要
1. 进程是什么?
进程 = 带权限限制的执行环境
= 保护后的地址空间 + 一个或多个线程 + 文件等资源
2. 为什么需要进程?
早期只有线程:
- 所有线程共享同一份地址空间
- 一个线程崩溃 → 全盘崩溃
- 线程可互相改写内存、窃取数据
- 线程可以改写操作系统 → 系统直接挂掉
进程 = 隔离 + 保护 + 权限
3. 进程核心特性
- 每个进程有独立地址空间
- 进程之间无法互相访问
- 一个进程崩了 → 不影响其他
- OS 受保护,不会被随意破坏
4. 进程 vs 线程(老师反复强调)
- 进程:资源容器、保护单位(地址空间、文件、权限)
- 线程:执行单位、活跃单位(PC、寄存器、栈)
- 一个进程至少有一个线程
- 同一进程内的线程共享地址空间
- 不同进程完全隔离
概念四:双重模式(Dual Mode)— 安全基石
1. 处理器至少两种模式:
内核模式(Kernel Mode / Supervisor)
- 全权访问所有资源
- 可以修改页表、关中断、操作硬件
用户模式(User Mode)
- 权限受限
- 不能修改页表
- 不能关中断
- 不能直接访问硬件
2. 为什么需要双模式?
防止用户程序:
- 霸占 CPU(死循环不放手)
- 破坏操作系统
- 访问别的进程数据
- 随意操控硬件
3. 如何进入内核模式?(仅三种合法入口)
- 系统调用(system call):进程主动请求服务
- 中断(interrupt):时钟、磁盘、网络等事件
- 异常 / 陷阱(exception/trap):除零、缺页、非法访问
→ 所有入口都由操作系统严格控制。
六、完整运行模型(老师最终总结图)
程序从磁盘加载
操作系统创建
进程
- 分配独立地址空间
- 建立页表
- 分配栈、堆
从入口开始执行,运行在用户模式
需要服务 → 系统调用 → 进入内核模式
内核完成操作,返回用户态
时钟中断触发 → 操作系统切换进程
七、本节课所有管理与作业提醒(全覆盖)
- 作业 0(Homework 0):立刻开始,熟悉工具、GDB、编译、虚拟机
- Project 0:明天发布,独立完成,不许合作
- 项目缓交天数(slip days):作业与项目共用 4 天
- 本周五是 退课截止日期(drop date)
- 可选 C/C++ 复习课:明天举行
- 课程全程使用 C 语言,项目在 Pintos 操作系统上开发
八、老师强调的易错点(必看)
- 线程不自带缓存,一个核的缓存被所有线程共享
- 线程不在 CPU 运行时,状态存在 TCB(内存里)
- 进程 = 保护单位;线程 = 执行单位
- 没有地址翻译 + 双模式 → 系统完全不安全
- 早期系统(Win3.1、Mac 早期)无强保护 → 极易崩溃
- 上下文切换需要保存与恢复 全部寄存器
九、本讲最终结论(老师原话总结)
现代操作系统建立在 四大基本概念 之上:
- 线程(Thread):执行流、虚拟化 CPU
- 地址空间(Address Space):内存视图
- 进程(Process):受保护的执行环境
- 双重模式(Dual Mode):内核态 / 用户态,安全基础
它们一起实现:虚拟化、隔离、保护、并发。