这门课解决什么问题
很多开发者学操作系统时,习惯直接看 Linux 内核源码或读《APUE》。这种学习方式有一个明显的盲区:你看到了系统调用的接口,却不清楚 CPU 到底在做什么。中断是如何触发的?进程切换时寄存器怎么保存?锁是如何利用 CPU 指令原语保证原子性的?这些问题用高级语言去解释,往往只能给出结论,无法展示机制。
这门课的核心价值在于「降维打击」。它不教你写应用层代码,而是直接从 x86-64 硬件架构出发,用汇编语言拆解操作系统最底层的实现逻辑。课程覆盖了单处理器多任务、多处理器并发、多线程切换,以及数据竞争、信号量、自旋锁、内存屏障等核心概念。你会发现,那些在高级语言中晦涩难懂的并发问题,在汇编层面其实是由几条特定的 CPU 指令(如 LOCK 前缀、MFENCE 等)精准控制的。通过这种视角的转换,你能真正理解操作系统是如何在硬件之上构建出并发模型的,而不是仅仅记住几个 API 的使用方法。
适合什么基础,建议先看哪几块
这是一门硬核的体系课,入门门槛不低。前提是你必须已经熟悉 x86 处理器的保护模式,了解分段和分页机制的基本概念。如果你对实模式到保护模式的切换过程一知半解,直接学习本课程会非常吃力。建议在正式进入本课程前,先补完《x86汇编语言:从实模式到保护模式》相关内容,建立对 CPU 工作状态的直观认知。
课程的知识结构层层递进。建议的学习路径如下:首先从 x86-64 架构基础入手,熟悉通用寄存器的扩展、指令集的变化以及寻址方式的差异,这是后续所有讨论的基石。接着重点攻克单处理器的任务切换,理解上下文切换在汇编层面的具体实现,包括栈的切换和寄存器压栈出栈的顺序。在此基础上,再深入多处理器场景下的同步机制,这是课程中最具挑战也最有价值的部分。不要跳过内存屏障和锁的实现细节,这些内容是理解现代 CPU 缓存一致性和并发性能瓶颈的关键。
学完能独立做什么
完成本课程后,你将具备从底层视角分析系统行为的能力。面对复杂的并发 Bug 或性能问题,你不再只能通过日志猜测,而是能够结合汇编指令和硬件特性,定位到底是锁竞争、缓存伪共享还是内存重排序导致了问题。你可以独立梳理出一个微型操作系统的内核调度流程,清晰解释每个系统调用背后 CPU 的状态变更。
配合资料包进行练习时,关键在于「动手模拟」而非「被动观看」。课程中涉及的汇编代码,建议自己在本地环境(如 VMware 或 QEMU)中逐行调试,观察寄存器值的变化。对于信号量和锁的实现部分,尝试脱离教材,仅凭对指令语义的理解,手写一份简化的线程同步模块。这种训练能帮助你建立起对硬件指令的肌肉记忆,让你在面对底层系统开发任务时,拥有一种穿透高级抽象、直击本质的工程直觉。
课程目录
汇报.png (1
29 KB, ) 2023-12-6 19:
27 上传 课程介绍: 具有计算机的使用经验,学过并熟悉x86处理器保护模式的内容。建议先学习《x86汇编语言:从实模式到保护模式》一书或者本讲师的同名视频课程。 介绍64位x86处理器的硬件架构、以及与操作系统相关的内容,包括:单处理器的多任务切换、多处理器的多任务切换和多线程切换、数据竞争、信号量、锁、线程同步和内存屏障等。注意:我们是用汇编语言来讲,而不是用高级语言!!!用汇编语言在硬件层级上讲上述内容,更透彻、更清晰!!! 课程目录: ├──{1}--内容提要及课程相关说明 | └──[1.1]--内容提要及课程相关说明.mp4
10.44M ├──{2}--X64基本架构和执行环境 | ├──[2.10]--X86处理器的物理地址空间.mp4
19.79M | ├──[2.11]--X64架构下传统模式的内存访问.mp4
8.35M | ├──[2.12]--传统模式下的32位4KB分页技术.mp4
9.28M | ├──[2.13]--传统模式下如何利用超过4GB的物理内存.mp4
11.70M | ├──[2.14]--传统模式下的32位4MB分页技术.mp4
34.40M | ├──[2.15]--传统模式下的32位PAE分页技术.mp4
9.18M | ├──[2.16]--传统模式下的32位PAE-4KB分页技术.mp4
46.83M | ├──[2.17]--传统模式下的32位PAE-2MB分页技术.mp4
17.15M | ├──[2.18]--X64架构的线性地址空间.mp4
18.70M | ├──[2.19]--扩高地址的特点和处理器检查.mp4
15.73M | ├──[2.1]--有关本章内容学习的重要提示.mp4
20.35M | ├──[2.20]--X64架构下IA-32e模式的内存访问.mp4
15.89M | ├──[2.21]--X64架构的段寄存器.mp4
13.84M | ├──[2.22]--X64架构下的代码段描述符.mp4
14.07M | ├──[2.23]--X64架构下的数据段描述符.mp4
9.52M | ├──[2.24]--X64架构下的4级和5级分页简介.mp4
16.92M | ├──[2.25]--X64架构下的系统表和系统描述符.mp4
12.91M | ├──[2.26]--X64架构下的GDTR.mp4
18.29M | ├──[2.27]--X64架构下的IDTR.mp4
19.36M | ├──[2.28]--X64架构下的LDT描述符和LDTR.mp4
11.14M | ├──[2.29]--X64架构下的TSS描述符和TR.mp4
10.13M | ├──[2.2]--X64架构的由来.mp4
16.53M | ├──[2.30]--X64架构下的标志寄存器和指令指针寄存器.mp4
29.54M | ├──[2.31]--X64架构下传统模式的寻址方式.mp4
14.41M | ├──[2.32]--X64架构下IA-32e模式的寻址方式.mp4
23.38M | ├──[2.33]--64位模式的RIP相对寻址方式.mp4
15.61M | ├──[2.34]--64位模式下的指令变化情况.mp4
18.89M | ├──[2.35]--IA-32e模式下的中断和异常处理概述.mp4
16.04M | ├──[2.3]--物理地址、有效地址和线性地址.mp4
12.99M | ├──[2.4]--X64架构的工作模式.mp4
11.67M | ├──[2.5]--IA-32e模式及其子模式.mp4
9.91M | ├──[2.6]--第一次阶段性巩固和测试.mp4
47.60M | ├──[2.7]--X64架构对通用寄存器的扩展.mp4
17.97M | ├──[2.8]--X64架构新增加的通用寄存器.mp4
9.38M | └──[2.9]--X64架构的通用寄存器访问规则.mp4
20.69M ├──{3}--准备进入IA-32e模式 | ├──[3.10]--调用BIOS例程显示字符串.mp4
20.12M | ├──[3.11]--读磁盘失败后的错误处理.mp4
24.81M | ├──[3.12]--准备读取内核加载器程序的剩余部分.mp4
20.66M | ├──[3.13]--转入内核加载器执行.mp4
80.36M | ├──[3.14]--检测处理器是否支持IA-32e模式.mp4
24.89M | ├──[3.15]--位测试指令BT.mp4
35.02M | ├──[3.16]--获取和显示处理器商标信息.mp4
25.63M | ├──[3.17]--获取和保存处理器的地址尺寸数据.mp4
18.93M | ├──[3.18]--显示处理器的地址尺寸信息.mp4
142.90M | ├──[3.19]--为进入保护模式准备全局描述符表.mp4
17.90M | ├──[3.1]--进入IA-32e模式的方法.mp4
10.48M | ├──[3.20]--进入保护模式.mp4
46.41M | ├──[3.21]--在保护模式下显示字符串.mp4
82.57M | ├──[3.22]--有关内核程序及其如何加载的说明.mp4
21.62M | ├──[3.23]--读取内核程序的第一个扇区.mp4
20.29M | ├──[3.24]--将内核程序完全加载到内存中.mp4
26.75M | ├──[3.2]--本章的目标及源程序的组织.mp4
25.58M | ├──[3.3]--主引导程序和NASM的文件包含功能.mp4
25.38M | ├──[3.4]--如何避免文件被重复包含.mp4
23.41M | ├──[3.5]--编写主引导程序的一般性建议.mp4
10.71M | ├──[3.6]--用BIOS硬盘扩展读加载内核加载器.mp4
16.55M | ├──[3.7]--在程序中使用NASM运算符和表达式.mp4
16.23M | ├──[3.8]--内核加载器程序的有效标志和长度.mp4
14.36M | └──[3.9]--通过数据段访问栈中的数据结构.mp4
8.94M ├──{4}--为进入IA-32e模式准备4级分页 | ├──[4.10]--创建与低端2MB物理内存对应的4级头表项和页目录指针表.mp4
18.94M | ├──[4.11]--创建与低端2MB物理内存对应的页目录指针项和页目录表.mp4
15.04M | ├──[4.12]--创建与低端2MB物理内存对应的页目录项.mp4
10.18M | ├──[4.13]--将物理内存低端的2MB映射到线性地址空间的高端.mp4
20.25M | ├──[4.14]--为多任务环境准备必要的4级头表项.mp4
14.07M | ├──[4.15]--为内核的4级分页系统预分配254个页目录指针表.mp4
15.65M | ├──[4.16]--在内核的4级头表内安装254个表项并清空相关的页目录指针表.mp4
22.36M | ├──[4.17]--进程上下文标识PCID.mp4
20.80M | ├──[4.18]--控制寄存器CR3的内容格式.mp4
10.59M | ├──[4.19]--设置控制寄存器CR3并开启物理地址扩展功能.mp4
9.77M | ├──[4.1]--4级分页的结构和原理.mp4
16.55M | ├──[4.20]--型号专属寄存器IA32_EFER的设置和分页的开启.mp4
25.42M | ├──[4.2]--2MB和1GB页面的4级分页方式.mp4
12.03M | ├──[4.3]--4级头表项的格式.mp4
21.10M | ├──[4.4]--页目录指针项的格式.mp4
17.43M | ├──[4.5]--页目录项和页表项的格式.mp4
10.00M | ├──[4.6]--4级头表的创建和初始化.mp4
12.94M | ├──[4.7]--创建指向4级头表自身的4级头表项.mp4
14.20M | ├──[4.8]--准备映射物理内存的低端2MB空间.mp4
33.21M | └──[4.9]--在4级分页中使用2MB的物理页.mp4
9.54M ├──{5}--进入IA-32e的64位模式执行 | ├──[5.10]--通用异常服务例程的工作过程.mp4
24.81M | ├──[5.11]--加载有效地址指令LEA.mp4
18.25M | ├──[5.12]--创建通用中断处理过程的中断门.mp4
20.55M | ├──[5.13]--在IDT内安装前32个与异常有关的中断门.mp4
23.06M | ├──[5.14]--在IDT内安装剩余的中断门并加载IDTR.mp4
18.09M | ├──[5.15]--初始化8259中断控制器.mp4
17.01M | ├──[5.16]--打印64位模式下的第一条信息.mp4
22.09M | ├──[5.17]--在虚拟机上观察内核的运行情况.mp4
12.70M | ├──[5.1]--在IA-32e的兼容模式下显示文本信息.mp4
26.72M | ├──[5.2]--通过远返回方式进入64位模式的内核.mp4
35.80M | ├──[5.3]--准备让内核工作在线性地址空间的高端.mp4
15.67M | ├──[5.4]--启用GDT和栈区的高端线性地址.mp4
22.69M | ├──[5.5]--使用RIP相对寻址将内核的起始线性地址改为高端地址.mp4
19.16M | ├──[5.6]--让处理器转到内核程序对应的高端位置继续执行.mp4
15.54M | ├──[5.7]--IA-32e模式下的中断门和陷阱门.mp4
15.31M | ├──[5.8]--IA-32e模式下的中断处理过程.mp4
17.22M | └──[5.9]--内核的文件组织与通用的中断和异常处理策略.mp4
22.55M └──{6}--单处理器环境下的多任务管理和调度 | ├──[6.10]--内核可用线性地址的获取和更新.mp4
23.81M | ├──[6.11]--立即数在64位模式下的长度限制.mp4
13.63M | ├──[6.12]--计算本次内存分配涉及的线性地址范围.mp4
14.09M | ├──[6.13]--获取与指定线性地址对应的4级头表项的线性地址.mp4
27.09M | ├──[6.14]--页面分配与页映射位串.mp4
17.28M | ├──[6.15]--页映射位串的定义和空闲页的查找.mp4
23.66M | ├──[6.16]--获取与指定线性地址对应的页目录指针项的线性地址.mp4
26.83M | ├──[6.17]--检查与指定线性地址对应的页目录指针项是否存在.mp4
11.64M | ├──[6.18]--分配页目录表并安装与线性地址对应的页目录指针项.mp4
15.03M | ├──[6.19]--安装与指定线性地址对应的页目录项、页表项和页面.mp4
20.36M | ├──[6.1]--单处理器环境下的多任务概述.mp4
24.38M | ├──[6.20]--64位LDT和TSS描述符的格式.mp4
15.63M | ├──[6.21]--创建和安装64位的TSS描述符并加载任务寄存器TR.mp4
27.18M | ├──[6.22]--实时时钟中断的安装和系统外壳任务简介.mp4
29.93M | ├──[6.23]--准备创建外壳任务.mp4
20.94M | ├──[6.24]--为新任务创建任务控制块PCB.mp4
18.12M | ├──[6.25]--为新任务创建4级头表.mp4
23.92M | ├──[6.26]--将指定的线性地址映射到指定的物理页.mp4
27.19M | ├──[6.27]--复制当前活动4级头表的内容给新任务的4级头表.mp4
16.13M | ├──[6.28]--切换到新任务的地址空间并清空4级头表的前半部分.mp4
15.35M | ├──[6.29]--为新任务分配0特权级使用的栈空间.mp4
22.05M | ├──[6.2]--快速系统调用概述.mp4
12.74M | ├──[6.30]--为新任务分配3特权级使用的栈空间.mp4
22.76M | ├──[6.31]--从硬盘上加载用户程序.mp4
19.54M | ├──[6.32]--生成任务标识.mp4
19.76M | ├──[6.33]--双向PCB链表概述.mp4
18.52M | ├──[6.34]--将新任务的PCB添加到PCB链表中.mp4
15.96M | ├──[6.35]--64位的任务状态段TSS和中断栈表IST.mp4
22.33M | ├──[6.36]--以中断返回的方式进入外壳任务的局部空间执行.mp4
22.22M | ├──[6.37]--系统调用指令SYSCALL和SYSRET.mp4
24.77M | ├──[6.38]--根据功能号计算内核例程的线性地址.mp4
27.96M | ├──[6.39]--快速系统调用的返回和指令的REX前缀.mp4
19.22M | ├──[6.3]--型号专属寄存器IA32_STAR.mp4
25.51M | ├──[6.40]--准备在时钟中断的处理中执行任务切换.mp4
31.38M | ├──[6.41]--执行任务切换.mp4
22.94M | ├──[6.42]--通过系统调用获取屏幕上可用的显示行坐标.mp4
20.27M | ├──[6.43]--通过系统调用获取当前时间.mp4
17.18M | ├──[6.44]--在外壳任务中显示当前时间.mp4
11.53M | ├──[6.45]--用户任务的结构和功能.mp4
23.01M | ├──[6.46]--当前任务标识的获取和用户程序例程库的介绍.mp4
20.43M | ├──[6.47]--将64位二进制数转换为十进制字符串.mp4
15.01M | ├──[6.48]--在每一轮相加中将结果和加数转换为字符串.mp4
23.08M | ├──[6.49]--字符串的连接和显示.mp4
18.22M | ├──[6.4]--准备在GDT中安装新的描述符.mp4
24.68M | ├──[6.50]--用户任务的终止.mp4
32.08M | ├──[6.51]--任务切换频次对用户体验的影响.mp4
40.36M | ├──[6.5]--为快速系统调用安装段描述符.mp4
25.62M | ├──[6.6]--为快速系统调用准备段选择子.mp4
13.84M | ├──[6.7]--设置快速系统调用的入口点.mp4
14.27M | ├──[6.8]--快速系统调用时的RFLAGS和栈切换.mp4
13.13M | └──[6.9]--动态内存分配和内核空间的分配策略.mp4
14.98M





