kernel-explain
Skill3 starsChanged 32 days agoMITView on GitHub
讲 Linux 内核原理的思路:内容按什么顺序、分几层讲,每层的材料去代码哪里取。本 skill 只放思路,不放技术事实 —— 事实每次从 user 指定的那棵内核树现查。动笔前先定读者目的(面试复习只讲核心技术的来龙去脉)、定树、定版本、定架构,再列小白的疑问链并按依赖排序,然后七层:① 一句话说这块在解决什么矛盾 ② 全貌图:硬件自己做什么、内核代码做什么、两边靠什么衔接(软件写好让硬件读的表和寄存器 / 硬件做不下去时进内核的异常入口),后文每个名词都要在图上有位置 ③ 主路径:从入口顺着最常走的分支读到底,一个具体例子贯穿 ④ 岔路:主路径第几步、什么条件、去哪(show_guard_chain.py 列条件)⑤ 演变线:从「什么都没有」讲起(如没有 MMU 的单片机),每个技术点按六格讲:没有它时 / 会怎样(带数字)/ 所以有了它 / 它怎么做 / 边界(上限多少、谁定的,芯片数字查 TRM)/ 代价(引出下一个点);讲通用原理时用读者的架构举例再给各架构对照表;设计意图从提交说明取(why_this_code.sh),取不到标 [推断] ⑥ 细节下沉:file:line、版本平台差异放最后 ⑦ 口述版:30 秒 / 2 分钟 / 追问。聊天里接追问时,第一句先说它在全貌图哪个位置。配 check_explain.py(E1–E9,md 和 html 都能查,带反向自测)。部件第一次出场时带一句「没有它会怎样」。TRIGGER: 讲内核原理 / 讲清楚 X 的原理 / 内核面试复习 / 整体框架 / 来龙去脉 / 讲本质 / 从设计角度讲 / 为什么这么设计 / 怎么演变来的 / 小白能懂 / 高维度讲 / 讲义太细记不住 / 这块的全貌 / 硬件流程和软件流程. DO NOT TRIGGER: 写或改内核代码(linux-kernel-dev)、讲一个代码改动(change-impact-brief)、只问用哪种形式讲(explain-ladder)、做页面的配色版式(anthropic-design 等)。
In this repository27 other files it gives its agents.
- anthropic-designSkill
- apple-designSkill
- atelier-designSkill
- datasheet-readingSkill
- design-evolveSkill
- design-plannerSkill
- design-reviewSkill
- design-tasteSkill
- doc-review-loopSkill
- doc-to-markdownSkill
- eclat-designSkill
- ember-designSkill
- explain-ladderSkill
- gated-dual-clone-auditSkill
- gated-dual-cloneSkill
- glass-designSkill
- graphite-designSkill
- hardware-3dSkill
- lectern-designSkill
- linux-kernel-devSkill
- md-to-pdfSkill
- primer-designSkill
- relief-designSkill
- sage-designSkill
- skills-syncSkill
- tech-pdf-readerSkill
- wechat-video-publisherSkill
The file
Files
讲内核原理:先全貌,后细节
2026-10-20 user 看完一份按问答整理的内存讲义后说: 「很精准没问题,但不适合复习面试使用,因为太多的细节,记不住」 「我们要用更高维度的角度去表达清楚这些问题的本质是什么,而不是一股脑钻入细节里面去, 所以讲一个问题要把整体框架讲清楚来龙去脉」 「不可能代码一开始编写就面面都能考虑完全,linux 内核也是长期发展下来才慢慢变出这么多设计」
0. 这个 skill 管什么
| 管 | 不管 |
| 讲的顺序、分几层、每层讲到什么程度 | 技术事实本身。事实每次从 user 指定的那棵树现查,不从本 skill 抄,也不凭记忆 |
| 每层的材料去代码哪里取、用什么命令取 | 用文字、图还是网页讲,句子怎么写:归 explain-ladder |
| 写完后的结构检查 | 页面配色版式:归 anthropic-design 等 |
为什么事实不放进来:同一个问题,板子上的 4.14 ARM32 和上游 6.x arm64 答案常常不一样。 放进 skill 的事实会过期。它还会被当成查过的结论直接用。本页出现的技术词只是为了说明写法。
1. 三种讲坏的方式
每一种单看都不算错,讲出来的事实也可能全对。
| 讲法 | 长什么样 | 读者的结果 |
| 按提问顺序排 | 把问答记录整理成文档:第 1 轮、第 2 轮…… | 每段都对,合起来没有一张图,记不住 |
| 按代码或教材顺序排 | 一个函数一个函数、一个模块一个模块讲,满篇 file:line | 适合查,不适合理解:不知道为什么要有这么多种 |
| 只追最新一问 | 每次只答眼前这一问,答得很深 | 要追问很多轮才拼出全貌。2026-10-18/19 一份 AI 问答记录,user 追问了 34 轮 |
共同的病:没有先给全貌。读者手里没有图,每个新知识点就没处挂。
2. 开工前:定读者目的、定树、定版本、定架构
先问这份东西给谁、拿去干什么,它决定讲多深。user 2026-10-20:「这个 html 是面试用我来复习的用的, 这个大前提不要忘记了,把内存管理主要的核心技术来龙去脉说清楚就好了」。
| 目的 | 讲到哪 | 不讲 |
| 面试复习 | 核心技术的来龙去脉;每个点的边界只留会被问到的一两条;出处折叠起来 | 旁支(别的架构的细节、很新的特性),除非被问到 |
| 实战排查 | 主路径和岔路要细到函数和条件;出处展开 | 演变线可以短 |
| 给新人讲 | 一句话、全貌图、主路径、演变线 | 细节和出处只给入口 |
T=<内核树> # user 指定的那棵;板子的问题用板子的树
git -C $T describe --tags # 版本
grep -E '^CONFIG_(ARM64|ARM|X86)=' <板子的 .config> # 架构;没有 .config 就问- 讲面试通用原理时,默认用上游较新的稳定版;讲 user 板子上的行为时,用板子那棵树。两者不一样时,⑥ 里列差异表。
- 换了树,前面查的
file:line全部作废,重查。
3. 七层
| 层 | 讲什么 | 讲到了的标准 | 材料去哪取 |
| ⓪ 疑问链 | 没学过的人会依次问的问题,按依赖排序 | 每个问题都能落到下面某一层 | user 的原话;再补上它们依赖的前置问题 |
| ① 一句话 | 这块在解决什么矛盾:「要 X,但 Y,所以 Z」 | 是矛盾,不是定义 | 对外接口承诺了什么 + 硬件给了什么限制 |
| ② 全貌图 | 硬件做什么 / 软件做什么 / 两边怎么衔接 | 后文每个名词都能在图上指出位置 | 写寄存器的地方、硬件读的表、异常和中断入口 |
| ③ 主路径 | 最常走的那条,从入口走到底,步骤编号 | 一个具体例子贯穿;不岔开 | 从入口函数顺着读;板上用 ftrace 抓一次真实路径 |
| ④ 岔路 | 第几步、什么条件、去哪、正常还是 bug | 「哪里会 / 不会 X」都在这层用表答 | 主路径函数里的 if / switch / 出错 goto |
| ⑤ 演变线 | 从「什么都没有」讲起;每个技术点:没有它时 → 会怎样 → 所以有了它 → 它怎么做 → 边界 → 代价 | 六格齐,会怎样带数字 | 引入它的提交说明、Documentation/、芯片手册(边界) |
| ⑥ 细节 | 数字、字段、file:line、版本平台差异 | 主线里没有,都集中在最后 | 当次查的那棵树 |
| ⑦ 口述版 | 30 秒、2 分钟、追问预测 | 能直接念出来 | 前六层 |
①② 给读者一张图,③④ 让他在图上走一遍,⑤ 告诉他图为什么长这样,⑥ 给要查证的人,⑦ 给要讲给别人听的人。
⓪ 疑问链:按依赖排,不按代码排
先写下一个没学过的人会问什么。2026-10-20 user 给内存列的就是一条,这条的写法值得照着做:
内存怎么申请 → 怎么访问到物理内存(硬件总流程)→ 用户空间和内核空间访问有什么不同 → 页表放在哪 → 哪里有缺页、哪里没有 → VMA 是什么 → 软件流程和硬件流程各走哪些 → 线性映射、非线性映射、回收是怎么演变出来的
排序只看一条:回答 B 要用到 A,A 就排前面。
① 一句话:写矛盾,不写定义
- 形状:「要 X,但 Y,所以 Z」。矛盾写清了,后面每个设计都能回到这句话上:它在缓解矛盾的哪一头。
- 反例:「X 是内核中负责管理 Y 资源的子系统。」这是定义,读完不知道难在哪。
<!-- ste-ok:反例 --> - 这句话通常没有一手出处,写的是自己的概括;
Documentation/里有原话就引原话。
② 全貌图:硬件、软件、衔接点
内核子系统几乎都能拆成三块。这是讲内核和讲一般软件最不一样的地方:
硬件自己做的事 衔接点 软件(内核代码)做的事
(不跑一行内核代码)
┌──────────────────┐ 软件写好、硬件去读 ┌──────────────────────┐
│ 按规则自动执行 │ ◀──── 表 / 寄存器 ──── │ 准备表、做决定、记账 │
│ │ │ │
│ │ ──── 异常 / 中断 ────▶ │ 处理硬件做不下去的事 │
└──────────────────┘ 硬件做不下去时叫软件 └──────────────────────┘三块各去代码哪里找:
| 块 | 找什么 | 怎么找(按架构改 $ARCH) |
| 软件写、硬件读 | 写系统寄存器、写设备寄存器的地方;硬件按固定格式去读的表 | git -C $T grep -n 'write_sysreg|msr\s' arch/$ARCH/ 再按子系统收窄;表格式看 arch/$ARCH/include/asm/ 里带 hwdef 的头文件 |
| 硬件叫软件 | 异常向量表 → 哪个 C 函数 → 子系统的处理函数 | git -C $T grep -n 'vectors' arch/$ARCH/kernel/entry*.S,从向量顺着跳转读到 C |
| 软件这一侧有哪些块 | 子系统目录、对外头文件、每块对外的几个函数 | 子系统目录下的文件名,include/linux/<子系统>*.h |
- 检查标准:后文出现的每个名词,都能指出它在图上哪个框。指不出来,要么图缺了,要么这个名词不该进主线。
- 部件第一次出场时带一句「没有它会怎样」,并指向 ⑤ 里它那一节。例:「TLB:没有它,每次访存都要先多读 4 次内存 → ⑤ A3」。 读者在 ②③ 里就知道每个部件为什么在那,不用等到 ⑤。
- 「X 放在哪」「X 是硬件做的还是软件做的」这类问题,在这张图上应该一眼能答。
③ 主路径:一条,走到底
- 选一个具体例子贯穿全文,后面讲岔路、讲演变都回到它。例子要小到能一步步走完:一条指令、一次系统调用、一次中断。
- 步骤编号。每步写:谁做(硬件 / 内核 / C 库)、读什么、写什么、数据在哪。
- 不岔开。出错、未命中、权限不对,这里都不讲,只在那一步旁边标「岔路 A」。
- 软件流程和硬件流程分开走。混在一起讲,读者分不清哪一步是谁在做。
取材:从入口(
SYSCALL_DEFINE、异常处理函数、中断处理函数)顺着读,只跟最常走的分支。 有板子时,用 ftrace 抓一次真实调用路径,比读代码猜的可靠:cd /sys/kernel/tracing 2>/dev/null || cd /sys/kernel/debug/tracing # 老内核在 debug 下 echo <入口函数> > set_graph_function echo function_graph > current_tracer; echo 1 > tracing_on # 触发一次,然后 echo 0 > tracing_on; cat trace > /tmp/path.txt- 调用链要正式出图时,用
design-review/scripts/gen_call_site_figure.py从文件按行号生成,不手抄。
④ 岔路:挂在主路径的步骤号上
| 主路径第几步 | 条件 | 走去哪 | 结果(正常还是 bug) |
- 「哪里会 X、哪里不会」「哪里能睡、哪里不能」这类问题都在这层答,用表。
- 取材:主路径上每个函数里的
if/switch/ 出错goto。某一行在什么条件下才执行,用linux-kernel-dev/scripts/show_guard_chain.py <file>:<line>列出外层所有条件,不要只看 grep 到的那一行。
⑤ 演变线:每个技术点都先问「没有它会怎样」
2026-10-20 user:「内存移动,内存回收,这些一开始是不会有的设计,是了解了本质后,慢慢遇到问题想出来的设计, 如果没有,会怎样,所以才慢慢有了这些设计」「没有 mmu 一样可以申请内存的,但是会面临什么问题,有些场景是没有 mmu 的例如单片机……tlb 也是同样的思路解释,没有 tlb 怎样,所以后面才诞生了 tlb」
起点是「什么都没有」,不是「已经有了一半」的系统。讲内存就从没有 MMU 的单片机讲起:它照样能申请内存, 问题出在别处。每一个技术点都是前一步撞上问题才加的,所以每个点都按这六格讲:
| 格 | 写什么 | 例:TLB |
| 没有它时 | 之前的做法,它照样能工作 | 每次访存都走 4 级页表 |
| 会怎样 | 具体场景、带数字,坏在哪 | 每次访存前先多读 4 次内存 |
| 所以有了它 | 一句话:加了什么 | MMU 里放一小块缓存记最近的翻译 |
| 它怎么做 | 两三句机制,够复述就停 | 先查缓存,没命中才走表,走完硬件填进去 |
| 边界 | 能力范围、上限、谁定的 | 项数由芯片定;能覆盖多大内存 |
| 代价 | 它带来的新问题,引出下一个点 | 缓存会过期,改了页表要作废 |
没有它时 ──撞上──▶ 会怎样(带数字) ──于是──▶ 有了它 ──代价──▶ 下一个点 ──▶ …- 六格必须齐。写不出代价,说明没想清楚,没有免费的设计。
- 问题要带数字或具体场景,数字从树里的常量算(页大小、级数、默认参数),算式写出来。
- 线可以有两条,对着全貌图的两半:硬件那一半怎么变的、软件那一半怎么变的。
- 这是逻辑上的演变,不是编年史。
- 引擎是「按你的想法做会怎样」。读者提一个更简单的方案,就按他的方案推下去,推到坏为止。 坏在哪一步,就是现有设计存在的理由。先承认他的想法里对的部分。
- 分清两种「为什么」:为什么需要(不这样就坏)和为什么选这个(还有别的路,为什么没走)。
- 「没有它时」最好有真实的样本:内核常常自己就留着没有它的那个版本,比如
CONFIG_MMU=n的无 MMU 模式和它的文档。 拿它当证据,比自己设想「没有它会怎样」可信。 - 边界写三件事:能力范围和上限是多少、由谁定(架构 / 具体芯片 / 内核配置 / 运行时)、去哪查。
- 架构和内核配置的上限:
Kconfig、页表格式的头文件、内核开机读的 ID 寄存器。 - 芯片定的数(TLB 项数、物理地址位数、ASID 位数):去查这颗芯片的技术参考手册(TRM),内核源码里没有。 user 的板子是哪颗核,就查哪颗核的 TRM;手册存一份到本地,出处写文档号和章节。
- 能在板上读的就读(
/proc/cpuinfo、ID 寄存器、/sys),读到的比手册更贴近这块板。 - 读者问「能不能随便扩」「是不是 128 位」这类问题时,答案就在边界这一格:谁定的、为什么不能随便改。
- 边界写几条看读者目的(§2):面试复习只留会被问到的一两条。
- 架构和内核配置的上限:
- 讲通用原理,用读者自己的架构举例,再给一张各架构对照表。 user 2026-10-20:「我这边主要是 arm32,arm64 的架构的, 哪怕以后是 x86 或者 riscv 等,这些通用原理都是一样的」。原理用一套话讲;对照表只列「同一件事在各架构叫什么」 (寄存器名、入口函数名),并写出它们在哪里汇合到同一段通用代码。对照表里每一格都要在树上核过。
取材:设计意图的一手记录是引入它的提交说明。
linux-kernel-dev/scripts/why_this_code.sh <file> [符号] # 谁、哪笔提交、提交说明怎么写的 git -C $T log -S'<符号>' --reverse --oneline | head -3 # 符号最早什么时候出现还可以看
Documentation/和 lore.kernel.org 上的讨论。取不到一手记录的设计意图,标[推断]。
⑥ 细节下沉
- 数字、结构体字段、
file:line、「这个版本这样、那个版本那样」都放最后的「细节和出处」一节。主线里最多留一两处会改变判断的。 - 下沉不等于不核。每个事实照样要有出处,只是放在后面。
- 版本、平台差异汇总成一张表:
git -C $T show <tag>:<file>对照着查,不散在正文里。 - 「某处没有 X」这种结论,写上搜索条件和范围,再用同一条件在一个确定有的地方搜一次,证明条件本身有效。
⑦ 口述版
- 30 秒:一句话 + 全貌图的三块。
- 2 分钟:主路径 + 一条演变线。
- 追问预测:每条一句答案,并注明展开时去第几层。
4. 写每一段时
| 做 | 说明 |
| 每节第一句就是答案 | 不写「下面我们来看……」这类预告 |
| 从读者的直觉出发 | 先说直觉里对的部分,再指出它在哪一步不成立,用一个具体场景演出来 |
| 一个例子贯穿 | 同一个例子从头用到尾,不每节换一个 |
| 对比用表 | A 和 B 的区别,按维度列成表 |
| 比喻最多一个,说清在哪失效 | 比喻帮读者记住结构,失效处防止他推错 |
| 不确定就标出来 | 设计意图写 [推断];没查的写「没查」 |
不做的:
| 不做 | 为什么 |
| 夸读者(「直觉非常敏锐」「神来之笔」) | 占篇幅,不带信息 |
| 夸张修辞(「灭顶之灾」「死个痛快」) | 读者分不清哪句是事实、哪句是修辞 |
| 讲得顺就当讲对了 | 讲得越顺,错处越难发现,见 references/lessons-from-qa.md |
| 每次回答末尾都问「要不要再聊 X」 | 追问集中放在口述版里 |
5. 和「技术解释五问」的关系
五问(是什么 / 没有它会怎样 / 为什么这么设计 / 什么场景用 / 机制)管一个名词,七层管一整块。 名词在七层里出场时,五问分到各层去答:
| 五问 | 在哪层答 |
| 是什么 | ② 全貌图上它那个框;第一次出场时带一句「没有它会怎样」 |
| 没有它会怎样 | ⑤ 它那一节的「没有它时 / 会怎样」 |
| 为什么这么设计 | ⑤ 它那一节的「所以有了它 / 代价」 |
| 什么场景用 | ③④ 主路径或岔路的第几步 |
| 机制 | ⑤ 的「它怎么做」只讲到能复述;再细的放 ⑥ |
五问之外,⑤ 每一节还多一格「边界」。
6. 三种场合
| 场合 | 做什么 |
| 写讲义或讲解页 | 定树 → 七层写满(大纲可从 references/outline-template.md 起步)→ 跑 §7 的检查。网页走 anthropic-design,图宽和句子走 explain-ladder |
| 聊天里接一个追问 | 第一句先定位:「这是全貌图里 X 那块,主路径第 N 步的岔路」,再答。还没给过全貌图,先画一张 ≤ 80 列的 ASCII 小图。一次只答这一问,但要让它挂在图上 |
| 改写旧资料 | 把问答记录或细节讲义拆成名词清单 → 每个名词放进七层 → 原文的 file:line 全部挪到 ⑥,并在当次的树上重核一遍 |
7. 检查
K=~/.claude/skills/kernel-explain/scripts
python3 $K/check_explain.py <讲义.md 或 .html>
printf '%s' "<草稿>" | python3 $K/check_explain.py --stdin
python3 $K/check_explain.py --strict <文件> # WARN 也算失败
python3 $K/check_explain.py --self-test # 19 条,15 条是故意写坏的| 编号 | 查什么 | 级别 |
| E1 | 有全貌图、主路径、演变线三节(只认小标题) | FAIL |
| E2 | 有一句话、岔路、细节、口述版四节 | WARN |
| E3 | 全貌图在主路径前,主路径在演变线前 | WARN |
| E4 | 有图,且第一张图出现在第一个 file:line 和第一段代码之前 | FAIL |
| E5 | 细节一节之外,file:line 不超过 3 处 | WARN |
| E6 | 演变线里「没有它」「代价」各至少 2 次,「边界」至少 1 次 | WARN |
| E7 | 演变线里有 [推断] 或提交号 | WARN |
| E8 | 没有夸读者、夸张修辞的词 | FAIL |
| E9 | 七层小标题下的第一句不是预告 | WARN |
退出码 0 过 · 1 有 FAIL(--strict 时 WARN 也算)· 2 用法错。
故意放的反例:Markdown 那一行写 explain-ok,HTML 元素加 data-explain-ok,E8、E9 跳过它。
检查只看结构:有没有、顺序对不对、主线里出处多不多。讲得对不对,靠当次在树上核。 讲没讲清,靠读者测试:新开一个 agent,只给它这份讲义,让它回答 ⓪ 那条疑问链。它答不出、答错的地方,就是没讲清的地方。
8. 文件
| 文件 | 作用 |
scripts/check_explain.py | E1–E9;md 和 html 都能查;--self-test 带「故意写坏,必须报」的用例 |
references/outline-template.md | 七层大纲空模板,只有结构 |
references/lessons-from-qa.md | 从一份 102 页 AI 问答记录里学到的讲法:哪些拿来用,哪些不学 |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

