系统学操作系统:CS537课程与OSTEP教材配套实践指南
这次我们来看一个能系统学操作系统的高质量资源威斯康星大学麦迪逊分校 CS537 操作系统课程Fall 2019中英双语字幕配套 OSTEP 教材。很多自学操作系统的同学最大的问题不是缺少资料而是资料太碎视频讲一套、教材讲一套、实验又是另一套学到后面概念和代码对不上。CS537 这套资源最大的价值就是把视频、教材、实验三件事串成了一条线。先说结论如果你想认真学操作系统而不是只想记几个进程状态图和调度算法应付期末这套资源值得收藏。它没有把概念拆成一堆不可验证的选择题而是让你从“操作系统设计者”的视角去看问题为什么需要进程、为什么需要虚拟地址、为什么并发这么难、文件系统崩溃了怎么办。这些东西一旦在实验里跑过、调试过后面再看面试题和 408 真题会觉得是在考你已经做过的内容。本文会围绕三件事展开第一这套资源包含什么、怎么和 OSTEP 配合第二怎么在本地搭一套能跑的实践环境把模拟器作业和课程实验跑起来第三遇到编译、调试、测试问题时怎么排查。全文所用命令都是通用模板具体路径和脚本名要以你拿到的课程材料为准。1. 核心能力速览能力项说明课程来源威斯康星大学麦迪逊分校 CS537Fall 2019字幕形式英文原声 中英双语字幕配套教材OSTEPOperating Systems: Three Easy Pieces教材有免费电子版课程主体视频讲解 课程讲义/幻灯片 课后作业 实验项目内容范围CPU 虚拟化、内存虚拟化、并发、持久化、分布式系统综述实验特点围绕 Linux 环境下 C 语言编程典型练习覆盖调度、shell、并发、文件系统等主题具体以课程材料为准硬件门槛普通电脑即可无需 GPU建议 8GB 内存以上系统要求建议使用 Linux 或 Windows Subsystem for LinuxWSL/虚拟机启动方式不是一键应用以命令方式运行模拟器作业、make 构建工程接口能力不支持 API这是学习型资源不是服务批量能力实验测试脚本可以批量运行常见形式如 make grade 自动评分适合读者考研 408、校招面试、自学系统方向、Linux 开发、嵌入式上面这个表可以快速判断这套资源适不适合自己。需要特别说明的是“实验特点”这一行没有写死具体题目是因为 CS537 不同学期、不同年份的实验内容会有调整有些年份围绕 xv6 做扩展有些年份用 pintos有些年份是自研的小型用户态线程库。你拿到资源后第一件事应该是看课程主页或 README 里的实验说明确认当年到底要做什么项目。OSTEP 这本书和配套作业则是基本固定的书后每一章都有“Homework”和“Projects”这些是很好的入门练习。2. 适用场景与学习边界先说适合谁。如果你正在准备考研 408操作系统部分一直停留在“背进程状态转换图、背调度算法、背银行家算法”的阶段那这套资源适合做深度补充。408 的题目偏基础但近几年越来越喜欢考“给一段并发代码问你有没有 race condition”“给你一个系统调用流程问你内核栈变化”这些光看国内教材不够需要真正理解设计动机。OSTEP 的讲解切入点恰好是“问题驱动”而不是“概念驱动”读完再做 408 真题很多原来只能死记的结论会变成可推导的结果。如果你是在准备校招面试尤其是后端开发、客户端开发、嵌入式、内核驱动方向这套资源的实验价值更高。面试最常问的几块进程和线程区别、协程调度、锁的实现、死锁条件、虚拟地址空间、页表和 TLB、文件系统 inode、零拷贝OSTEP 都有对应章节而且给了可运行的小例子。你可以一边看视频一边把书里的 C 语言小 demo 改一改加深记忆。如果你只是想通过期末考试不打算动手写代码那这套资源不一定适合。它不是速成课视频时长不短实验投入时间更多。只想要题库和重点整理的话直接用国内教材加真题更高效。使用边界也要说清楚。课程视频和教材属于作者与学校的公开教学资源OSTEP 官网允许免费阅读电子版但使用时仍建议遵守原作者的许可协议。字幕文件、视频文件、实验模板这些资源只用于个人学习不要二次打包传播更不要拿去商用。涉及课程代码和作业答案很多学校有学术诚信要求如果你是在读学生不要直接抄袭在线公开的 project 答案容易出问题。3. 学习前环境准备与前置条件3.1 基础要求开始之前最好具备三个前置条件C 语言基础能看懂指针、结构体、malloc/free能写几十行的小程序。OSTEP 里的示例代码大量使用指针和链表实验项目更不用说了。数据结构基础至少懂队列、链表、栈、哈希表。调度器、线程池、文件系统缓存都离不开这些结构。Linux 命令行基础会 cd、ls、mkdir、vim/nano、gcc、make。实验基本都是命令行环境不会用终端会非常难受。如果 C 语言很生疏建议先用两周复习《C Primer Plus》前 12 章或者直接看 OSTEP 附录里的 “The C Programming Language” 速成章节然后动手写几个链表程序再回来。3.2 操作系统环境课程实验不要求特定发行版但建议使用 Ubuntu 或 Debian 系的 Linux 系统。如果你电脑装的是 Windows有两个选择WSL2安装 Ubuntu适合跑模拟器作业和大多数 C 语言实验。虚拟机安装 VMware/VirtualBox Ubuntu和真机一致但性能略差。如果你用的是 macOS也能跑大部分 C 语言实验但涉及时钟中断、虚拟内存等底层实验时建议还是开一台 Linux 虚拟机能少踩很多坑。3.3 安装工具链在 Ubuntu/Debian 下打开终端执行sudo apt update sudo apt install -y build-essential git gdb qemu-system-x86 python3 python3-pip vim一些老的实验工程可能依赖 32 位库比如早期版本的 xv6 或 pintos 的编译环境建议顺手装好sudo apt install -y gcc-multilib libc6-dev-i386安装完成后验证工具链是否可用gcc --version make --version qemu-system-x86_64 --version python3 --version如果这些都正常输出环境基本就绪。3.4 目录规划操作系统学习会持续几周甚至几个月建议一开始就把目录规划好不要所有文件堆在桌面mkdir -p ~/os-learning/notes mkdir -p ~/os-learning/book mkdir -p ~/os-learning/resources mkdir -p ~/os-learning/projectsnotes放自己的笔记和思维导图。book放 OSTEP 电子版或 PDF。resources放视频、讲义、作业模拟器。projects放课程实验代码。目录分开的好处是后面跑实验、写笔记、复习面试时能快速定位不会出现“这个实验我写在哪了”的问题。4. 资源的内容结构与配套关系4.1 “OSTEP 三件套”到底是什么很多人听到“OSTEP 三件套”会以为只是三本书其实不是。从 CS537 这套资源的组织方式来看三件套通常是指教材Operating Systems: Three Easy Pieces课程视频和讲义CS537 的教学录像、幻灯片、课堂笔记作业和实验OSTEP 课后模拟器作业 课程 Project教材负责把原理讲清楚视频负责把教材内容变成可听的讲解实验负责把原理变成能跑的代码。三者缺一不可。只看视频不看实验会觉得自己懂了但一动手就是各种段错误只啃教材不做模拟器作业调度算法、分页机制永远是纸面上的公式。4.2 教材章节与操作系统知识模块OSTEP 整体分为四大块这个结构和 CS537 的教学顺序基本一致知识模块核心章节学习重点对应面试/考研问题虚拟化进程、进程API、机制受限直接执行、调度、地址空间、内存API、地址转换、分页、TLB、多级页表、swapCPU 如何虚拟化、内存如何虚拟化进程状态、上下文切换、进程调度算法、虚拟内存、页表、缺页中断并发线程、锁、自旋锁、队列、条件变量、信号量、并发bug、基于事件的并发race condition、原子性、死锁、活锁互斥锁、自旋锁、读写锁、生产者消费者、死锁条件、线程池持久化I/O、磁盘、RAID、文件系统、目录、崩溃一致性、日志、LFSinode、目录项、日志恢复、写放大硬链接、软链接、文件描述符、零拷贝、日志文件系统杂项虚拟化综述、分布式系统综述、安全设计哲学的总结分布式一致性、快照、虚拟化安全这个表格适合当复习提纲用。你在学完某一章后可以对着表格自问这一块我能不能用自己的话讲清楚如果不能回到对应章节再看一遍。4.3 CS537 课程实验和教材的关系课程实验通常不是教材内容的直接复制而是把教材里的某个原理放大成一个可运行的工程。例如学完调度算法实验可能要求你实现一个用户态线程调度器把 FIFO、Round Robin、MLFQ 都写一遍然后对比不同策略下的平均等待时间。学完虚拟内存实验可能要求你实现一个地址转换模块模拟多级页表和 TLB。学完并发实验可能要求你实现一个带锁的线程池或者给一组并发程序找竞态条件。学完文件系统实验可能要求你实现一个简易文件系统支持文件创建、删除、读取并保证掉电后数据不损坏。这类实验的评分通常有自动化脚本例如make grade或python3 grade.py。你不需要自己判断“我这个结果对不对”脚本会告诉你哪些测试点过了哪些挂了。这学起来效率很高因为反馈是即时的。5. 推荐学习路线与实操步骤5.1 第一阶段用两周建立整体框架建议不要上来就啃完整本书。先用 1 到 2 周时间按顺序看完课程前 6 讲大概覆盖进程、中断、调度初识。每看完一讲翻一遍 OSTEP 对应章节把课后“Homework”题做 2 到 3 道。这个阶段的目标是建立“操作系统在解决什么问题”的直觉而不是记住所有细节。5.2 第二阶段跑通模拟器作业OSTEP 的课后作业里包含大量 Python 模拟器这是它最大的特色之一。比如 CPU 调度作业里的调度模拟器可以让你直观看到 FIFO、SJF、RR 在不同任务序列下的表现不用写一行 C 代码就能理解调度公式。先从最简单的调度模拟器开始cd ~/os-learning/resources # 以 CPU 调度模拟器为例具体目录名以实际资源为准 python3 scheduler.py -h查看帮助后跑一个 FIFO 调度python3 scheduler.py -p FIFO -j 3 -s 1输出会显示三个任务的到达时间、执行时间和完成时间。你可以试着改任务数、种子、时间片长度观察平均周转时间怎么变化。跑通一个模拟器后再依次尝试内存分页、TLB、并发锁这几个主题的模拟器。这类模拟器对系统性能几乎零压力普通办公本也能秒开。遇到ModuleNotFoundError时先用pip3看缺什么依赖一般按报错装包即可。5.3 第三阶段选一个实验工程深入做视频里看懂和代码里跑通完全是两回事。CS537 课程实验通常提供一个基础工程模板你需要在里面补全核心函数。典型流程是获取实验代码。阅读 README了解实验结构。找到标着TODO或LAB的源文件。实现后运行测试脚本。以 xv6 方向的实验为例常见的启动流程是cd ~/os-learning/projects git clone https://github.com/mit-pdos/xv6-public.git xv6 cd xv6 make make qemu-noxqemu-nox表示在没有图形窗口的终端里启动 QEMU 模拟器。启动后你会看到类似 Linux shell 的提示符里面可以运行ls、cat、forktest等命令。如果出现QEMU: Terminated或make: *** [qemu-nox] Error 1多半是 QEMU 没装好或者当前用户没有/dev/kvm权限。如果课程实验基于 pintos流程也很相似cd ~/os-learning/projects/pintos/src/threads make pintos run alarm-multiplepintos 专门用于教学自带线程调度、用户程序、虚拟内存、文件系统四组实验难度比模拟器大一个档次但做完收获也明显更大。5.4 第四阶段对照面试题和考研真题做输出实验做完一部分后建议把知识点转成文字输出。你可以开一个 GitHub 仓库或者本地笔记用“问题 答案 代码片段”的形式记录。例如什么是上下文切换xv6 的swtch函数在做什么为什么 TLB 需要 TLB shootdown多核环境下怎么处理自旋锁和睡眠锁的本质区别是什么文件系统的 inode 和目录项分别存储什么信息这些输出不是为了发博客而是为了暴露“以为自己会了、其实讲不清”的部分。面试前拿这份笔记复习效果远超重新看一遍视频。5.5 第五阶段把实验成果整理成作品集如果时间允许挑一个完成度最高的实验整理成项目文档包含实验目标我实现了什么关键数据结构运行效果截图或测试输出遇到的问题和解决过程这段内容可以写进简历也可以当作社媒分享的素材。对校招同学来说一个能讲清楚设计细节的 OS 实验项目比一堆“熟悉 Linux”空话有用得多。6. 关键实验与调试技巧6.1 用 GDB 调试 xv6如果课程实验和 xv6 相关调试会用到 QEMU GDB 的远程调试模式。先启动带调试支持的 xv6make qemu-gdb这时候 QEMU 会停下来等待 GDB 连接。再开一个终端进入 xv6 目录gdb kernel (gdb) target remote localhost:26000 (gdb) b sys_fork (gdb) c执行到sys_fork时程序会中断你可以看到内核栈、函数参数、寄存器信息。这种调试方式能非常直观地理解系统调用从用户态到内核态的路径。如果target remote localhost:26000连不上常见原因是先启动了普通make qemu再启动 GDB或者端口被占用。先按CtrlA再按X退出 QEMU重新用make qemu-gdb启动。6.2 用 AddressSanitizer 找内存错误课程实验里的 C 代码经常伴随数组越界、use-after-free 这类问题。用-fsanitizeaddress编译可以快速定位gcc -g -fsanitizeaddress -o test test.c ./test如果程序有问题会直接输出出错的源码行和内存地址比手动 debug 快很多。6.3 跑自动化测试实验模板里通常有测试脚本。以 make 体系为例make grade输出会是类似test 1: fork: PASS test 2: exec: PASS test 3: sched: FAIL看到 FAIL 后不要急着看答案。先找到对应的测试用例源码理解它想验证什么行为然后在自己的实现里加printf或使用 GDB 打断点。这个过程本身比项目实现更有价值因为它训练的是调试和定位问题能力。7. 资源占用与性能观察这套学习环境没有任何 GPU 需求所以不用担心显存。重点看 CPU 和内存。操作系统实验属于 CPU 密集但不重的负载。编译 xv6 或 pintos 时CPU 占用会短时冲到接近 100%但通常几秒到几十秒结束。运行 QEMU 模拟器时单核占用会持续在一半以上这是正常现象不是系统卡死。观察资源占用最简单的方式是top按1可以看每个 CPU 核心使用率。想更直观可以安装htopsudo apt install -y htop htopQEMU 模拟一个教学操作系统镜像内存占用通常不大2GB 内存的虚拟机跑起来也没问题。如果你开的是 WSL2 或虚拟机宿主机 8GB 内存是更稳妥的选择。编译时如果出现virtual memory exhausted或gcc: fatal error: Killed signal terminated program cc1一般是物理内存或交换分区太小可以关掉浏览器再编译或者扩大交换分区。8. 常见问题与排查方法问题现象可能原因排查方式解决方案视频英文字幕看不懂词汇量或专业术语不熟先看课程讲义再回来听视频把 OSTEP 章节词汇做成单词表配合双语字幕看双语字幕时间轴对不上播放器字幕偏移设置缺失检查字幕偏移设置手动调整字幕偏移或换用 PotPlayer/VLC 等播放器python3 scheduler.py报 ModuleNotFoundError缺 Python 依赖看报错模块名用 pip3 安装对应模块gcc编译报缺少头文件缺少 32 位开发库file查看目标架构检查报错文件安装 gcc-multilib 和 libc6-dev-i386make qemu-nox启动失败QEMU 未安装或版本不匹配执行qemu-system-x86_64 --version重新安装 QEMU或按 README 指定版本GDB 连不上 QEMU端口号不对或 QEMU 没启动先启动 Makefile 里的 qemu-gdb 目标换端口常见为 26000查看 Makefile 确认实验测试 FAIL实现逻辑不完整打开测试用例读断言用 GDB 打断点对比输出 diff知道概念但不会写实验代码实践量不足先从最小 demo 开始把实验拆成小函数逐个实现每实现一个跑一次测试视频学完感觉全忘缺少主动输出合上视频回忆章节结构用费曼方式写笔记用自己的话改写实验代码在 macOS 上编译失败系统调用和链接差异查看 Makefile看是否依赖 Linux 特有接口统一在 Linux 虚拟机或 WSL 里跑9. 最佳实践与学习建议9.1 先小规模验证再大规模投入第一次跑模拟器不要直接挑战“全部作业做完”。选一个简单练习比如调度模拟器设置 3 个任务观察输出。跑通后再逐步增加任务数量和复杂度。实验代码也是这样先把一个系统调用或一个调度队列实现好跑过测试再继续下一个。9.2 保留一套最小可运行环境操作系统实验经常遇到“今天能编译明天为什么报错了”的情况。建议把课程指定的 gcc 版本、QEMU 版本、make 版本记录下来写成 README 放到项目根目录。如果只是学习用途可以直接用 Docker 装一个固定版本的 Ubuntu 环境docker run -it --name os-dev ubuntu:20.04 bash在容器里安装工具链再挂载项目目录。这样宿主机再怎么更新实验环境也不会被破坏。9.3 模型文件、输入素材、输出结果分目录管理放到操作系统学习里就是代码、笔记、作业输出、临时文件分目录放。之前建议的notes/book/resources/projects就是一套简单的分层。项目目录里还可以再分src、tests、logsmkdir -p ~/os-learning/projects/xv6/src mkdir -p ~/os-learning/projects/xv6/tests mkdir -p ~/os-learning/projects/xv6/logs临时调试文件不要乱放在仓库根目录如果以后要做项目展示目录干净能省很多事。9.4 做实验要留下日志和复盘记录出现一个 bug修完就完事了这是效率最低的做法。更合理的做法是记录现象、定位过程、最终修复方案。下次面试或写博客时直接翻这些记录就是现成的项目素材。批量任务或者连续多个测试点失败时先修第一个再跑全部避免多 bug 混在一起不好定位。9.5 接口类或服务类内容别暴露到公网虽然这套课程不涉及 API 服务但如果你照着实验代码改造成了一个本地起服务的小系统记得监听127.0.0.1不要监听0.0.0.0。开放到局域网后如果代码有问题别人可以直接连上来存在安全风险。所有实验服务默认只给本机调试用就好。9.6 注意版权与合规课程视频、字幕、讲义、教材电子版这些都是公开教学资源使用时要尊重原作者的许可协议。OSTEP 教材官网提供的电子版主要用于个人学习不要把它转成 PDF 到处传播不要拿来卖钱。字幕文件如果作者没有明确说可以分发同样只自己看。涉及写博客分享学习心得引用图表时要标明出处实验代码如果基于课程模板也要说明来源。10. 总结这套资源最值得尝试的点是它把操作系统从“概念课”变成了“工程课”。教材、视频、实验三者搭配跟着走一遍你对进程调度、虚拟内存、并发同步、文件系统这些核心模块的理解会明显比只看知识点串讲深很多。建议你先做两件事下载或确认拿到课程视频和英文讲义后看第 1 章“进程”和第 4 章“调度”对应的视频然后立刻跑一个 OSTP 调度模拟器观察不同调度策略的差异。前者建立全局观后者验证你确实能动手。最容易踩的坑是“只收藏不实践”资源囤积得再多知识不会自动进入脑子。看到 FAIL 不要慌回到教材对应章节用 GDB 或打印日志看实际行为绝大多数问题都能在这两步里解决。后续如果想继续深入可以接着做 MIT 6.S081 的 xv6 labs或者把 CS537 的实验项目做二次改造比如给自己的调度器加一个负载均衡策略。操作系统学习的核心是动手这套 CS537 OSTEP 的资源已经把动手路线铺好了剩下的就是一步步跑起来。