操作系统

Book Notes · LKD · Design Choices

Linux 内核设计与实现
开发者视角入门

Robert Love 写「为什么这样拆」。字段级实现、老版本函数表见 ULK。两本书都对应较老主线,不能当现行内核文档。先会用全书讲清机制,再打开本页。

01和 ULK 怎么分工

LKD 适合问:为什么进程和线程共用一种描述符、为什么小对象不直接找伙伴系统。ULK 适合问:描述符里有哪些链、缺页时先碰哪张表。

408 机制→LKD 取舍→ULK 实现

Linux 是可加载模块的单体内核:多数服务在内核态,但不必一次链死所有驱动。这和微内核「服务外移」不是同一条设计。

易错:不要把 LKD 的「轻」读成「比 ULK 更新」。两本都可能落后于主线;机制对错仍以全书为准。

02内核里的同步

用户态有互斥锁与条件变量;内核还有关中断、自旋锁、RCU 等。选择依据是:能不能睡眠、临界区有多长、是否在中断上下文。

生产者—消费者仍要遵守 P 的次序:缓冲区满时生产者先占互斥再等 empty,会和必须拿互斥才能取出的消费者卡死。这是全书口径,不随内核原语改名而变。

进阶 / 超纲seqlock、per-cpu 计数、RCU 宽限期的实现,408 不要求。

03内存与块层取舍

伙伴管页框,slab 管小对象:这是「先按页、再按对象」的两级决定,不是两种互相替代的 408 算法。页缓存让文件 I/O 先走内存;脏页回写是写回策略,不要和「换入」混称。

块设备上的 SCAN / LOOK:LOOK 到当前方向最后一个请求就掉头,SCAN 还要走到盘臂端点。这是磁盘调度,不是页面置换。

进阶 / 超纲多队列块层、I/O 调度器名称随版本变化,不要默进统考。

章末自测

先全书,再 LKD 看取舍,需要字段级再进 ULK。不要两本同时当现行源码手册。
区分。资源是否共享由 clone 标志决定。408 仍写:进程分配资源,线程参与调度。
不能。约束是「持有自旋锁期间 / 原子上下文不能睡眠」,不是「路径可能睡眠就不能用自旋锁」——持锁区外可以睡眠。睡眠调度会破坏原子上下文约束。