操作系统

Book Notes · ULK · Implementation

深入理解 Linux 内核
机制实现深读

Bovet & Cesati 把 408 里的进程、内存、文件接到某一代 Linux 的数据结构上。常见中译本对应较老主线(约 2.6),不能当现行内核文档。设计取舍见 LKD;本页只盯实现怎么落。

01进程描述符

408 的 PCB 在 Linux 里主要落在 task_struct。它描述一个可调度实体,不是「一个用户看到的程序」的同义词。

描述符里常见几组字段:标识与亲属(pid、父/子/兄弟)、状态、内存描述、打开文件、信号、调度参数。fork 在规范里要求逻辑复制用户地址空间;写时复制是常见实现,不是 POSIX 定义本身。

task_struct→mm / files / signal→可调度实体
进阶 / 超纲pid 命名空间、thread_info 与内核栈的具体布局、thread_group 与轻量进程的字段级对照,统考不要求默写。

02调度实现

教材里的 FCFS / RR / 优先级,在内核里变成某个就绪队列 + 选下一个 + 上下文切换。ULK 第 3 版对应 2.6.11,书中为 O(1) 调度器;后来的 CFS(2.6.23 合入)/ EEVDF 已超出该书版次。不要把某一版函数名当 408 答案。

进程分配资源,线程参与调度:Linux 用同一套 task_struct 调度,用共享 mm 区分「是否共享地址空间」。clone 的标志位决定复制哪些资源。

易错:陷入或缺页返回用户态前可能引起调度,不要写成「系统调用直线返回」。并发是重叠推进,并行是同一时刻同时执行。
进阶 / 超纲红黑树就绪队列、vruntime、EEVDF、组调度、实时类与普通类如何并存,标超纲。本站后续专题再写演化。

03内存:伙伴与 slab

页框分配常用伙伴系统:按 2 的幂合并/拆分空闲块,减轻外部碎片。内核小对象再用 slab / slub 一类缓存,避免每次都向伙伴要整页。

缺页:P=0 只是状态;访问合法页才缺页。有空闲框直接装入,无空闲才置换。这和全书、CSAPP 虚存章一致。

进阶 / 超纲zone、迁移类型、kmem_cache 内部、反向映射、匿名/文件页的具体回收路径,不进 408 简答。

04VFS 架构

VFS 把「打开、读、写、目录」收成一套与具体文件系统无关的对象:超级块、inode、目录项、打开文件。ext4、tmpfs、proc 都挂在这套接口后面。

fd→打开文件→inode / 页缓存

用户看见的是 fd。短读短写仍合法。dup2 关闭并复用目标 fd 是内部原子操作。

进阶 / 超纲dentry 缓存、挂载命名空间、具体文件系统的盘上布局,统考不要求。

章末自测

它是可调度实体。是否共享地址空间由 mm 等字段决定。不要把「一个 task」直接说成「一个用户进程」而不看共享关系。
主要减轻外部碎片(空闲块合并)。内核小对象的内部碎片更多靠 slab 一类缓存处理。
不能。408 要 FCFS / RR / 优先级 / 多级反馈这些模型。某一版 Linux 的实现标超纲。