From 0265dc786d6730282d4402bfd001d1c0e04f62a4 Mon Sep 17 00:00:00 2001 From: gatieme Date: Fri, 7 May 2021 23:37:58 +0800 Subject: [PATCH] description: readme --- study/kernel/00-DESCRIPTION/README.md | 140 ++++++++++++++++++++------ 1 file changed, 110 insertions(+), 30 deletions(-) diff --git a/study/kernel/00-DESCRIPTION/README.md b/study/kernel/00-DESCRIPTION/README.md index e5f107d..772151f 100644 --- a/study/kernel/00-DESCRIPTION/README.md +++ b/study/kernel/00-DESCRIPTION/README.md @@ -7,37 +7,105 @@ Linux 内核特性演进史 个人理解, 对于知识不细究, 不总结, 学到的东西永远不成系统. 不系统的知识永远只是一盘散沙. -# 1 为什么需要这样的内容 +# 1 Linux 内核学习方法 ------- -自己在学习内核的过程中, 一直在思考怎样让自己的知识成体系, 而不是一盘散沙. +## 1.1 发问 +------- + + +在上学的时候一直就是内核很产生了兴趣. + +刚开始本科那会搞嵌入式, 当时主要在开发上层应用, 但是偶尔也需要重新编译下内核, 改改内核参数. 虽然都是照着开发板提供的教程, 无脑操作. 但是却对内核产生了浓厚的兴趣. + +硕士的时候, 靠着陈莉君老师的 《Linux内核设计与实现》 入了门, 开始自己看内核源代码. 当时也没加什么技术群, 纯粹靠着一腔热血, 阅读代码, 记记笔记, 写写博客. 遇到没想明白的, 就慢慢琢磨、码代码实践, 虽然痛苦, 倒也充实. + + + +### 1.1.1 Linux 内核应该如何学习 ? +------- + +但是即使代码看了不少, 博客写了不少, 总感觉自己和内核之间隔着一层纱. 好像看的也还算清楚, 但是总有东西隔着, 模模糊糊. +一直在思考, 这层纱, 到底是什么 ? 怎么才能捅破它 ? + +* 都说实践出真知. 我实践了不少, 但是真知还是没摸透, 至少只是一知半解, 甚至仔细想想, 可能一知半解都不算. + +* 都说功夫不负苦心人. 功夫下了不少, 花了多少个日日夜夜, 分析代码, 做实验, 但是内核的学习还是没学到"内核". + +问题出在哪里? 内核到底该怎么学, 才能让自己成长最快, 理解最深? + +### 1.1.2 我们与社区的一些大牛的差距在哪里 ? +------- + +看着社区邮件列表里面各路大神, 各显神通. 各种 bugfix, 各种特性, 甚至各种性能优化补丁简直信手拈来. 大佬们之间侃侃而谈, 相互之间的讨论内精确到每个细节, 外扩展到对相关特性的影响. 看着每天邮件列表的一封封邮件, 让自己有一种恍惚:内核可能没那么难. + +不, 难于不难, 只是对人. + +想起来一句话, 人与人之间的差距, 有时候比人跟猩猩要大. + +话虽然难听, 但是在理. + +所以我们跟社区大佬之间的差距在哪里? + +很长时间我一直在思考这个问题. 社区的大牛们, 在早期就参与内核开发, 对所负责模块及其相关, 有一个非常清楚的认知. 这个认知是形成了一个玩咸亨的体系的. + +他们从这个模块最初的时候就开始参与, 一点点实现, 一点点优化, 他们清楚的了解整个开发的历史, 也知道每个子特性、子优化的实现细节. + +1. 包括当前模块的设计思路和整体框架, 有没有备选方案, 为什么选择当前这个方案. 所有的这些方案有什么优点, 有什么缺点. 哪里还能继续改进. + +2. 当前对该模块的这些改动都需要注意哪些细节, 可能影响哪些模块. 会导致什么样的问题. + +总结来说, 大佬们长期参与, 对当前模块形成的知识体系, 不是简单看代码、解决几个问题, 就可以形成的. 这是对整个模块全局的把控. 这个知识体系自顶向下, 逐步细化. 包含了模块中每个子模块子特性的总体和细节. + +如果把这个模块比作一颗树. 那么树干就是对整体的认知, 而每个大的树杈都代表着一个子特性, 而依附在每个树杈上细小的树枝, 则是各个子特性细节的, 每个树枝上的树叶和新芽, 则是这些细节的各种详细的描述和理解. + +这棵树上结出了无数的果子, 但是只有我们爬过(学习)了买个树杈, 摸索了每个细节(果子所在的树枝), 才能收获果实. + +而随着时间的推移, 内核不断发展, 这棵树(内核子模块, 不如调度、内存管理、文件系统等)也更加繁盛. 而我们攀爬它摘果子的难度就会越来越大. + +如果想做内核这个模块有深入的理解. 那么我们必须构建这个模块完整的知识体系. +虽然困难, 但是也不是不可行. 我们也是需要顺着树的脉络和枝杈, 不断摸索, 不断地去了解他. 方法也是:自顶(根和树干)向下(树叶), 逐步细化. 从树根开始爬起, 慢慢的爬过一个树杈, 接着另外一个. + +> PS : +> 当然你也可以走捷径. +> 如果你使用工具把果实摘下来, 那么我们可以理解为, 是别的兄弟(工具)帮你摘的果实. +> 所以这不在我们讨论的范畴. + +### 1.1.3 如何形成系统的内核知识 ? +------- + +因此自己在学习内核的过程中, 一直在思考怎样让自己的知识成体系, 而不是一盘散沙. 我们学习内核的过程其实和一颗颗树苗茁壮成长, 最后发展成一个森林的过程很像. 我们把内核中每个模块都当成一个小树苗, 我们学习就是呵护这些小树苗成长成参天大树. 当然我们建议, 我们先培养一颗参天大树, 这颗树会成为我们整个森林(知识体系)中最繁茂, 最稳固的根基, 为我们其他模块(树苗)遮风挡雨, 庇护他们成长. -> 有一棵树, 天天梦想着变成一个森林, 但是他一直不知道该怎么办. +> 我们是一名勤劳的护林员, 天天梦想着种出一片森林, 但是我们一直不知道该怎么办. -## 1.1 萌芽 +## 1.2 内核学习路线(方法论) ------- -1. 第一个阶段(萌芽) : 首先你需要了解一些操作系统相关的基础概念和原理. 这种通过一些教材或者概要性的书籍来获取就可以了. 如果你是科班出身或者已经对这些概念了熟于心, 请忽略此阶段. 这个阶段完成后, 我们的森林中已经有了一颗颗破土而出的小树芽, 我们具备了内核的一些基础知识, 但是刚刚萌芽, 并不繁茂. - -## 1.2 繁盛 +### 1.2.1 第一个阶段(萌芽) ------- -第二个阶段(繁盛) : 你可以从自己感兴趣的某个模块入手, 去阅读 Linux 内核代码. 这个过程也可以结合一些书籍来看, 特别是一些附带源码分析的书籍. 这对你对整个模块的体系和原理有一些深入的理解. 这个过程由浅入深. +首先你需要了解一些操作系统相关的基础概念和原理. 这种通过一些教材或者概要性的书籍来获取就可以了. 如果你是科班出身或者已经对这些概念了熟于心, 请忽略此阶段. 这个阶段完成后, 我们的森林中已经有了一颗颗破土而出的小树芽, 我们具备了内核的一些基础知识, 但是刚刚萌芽, 并不繁茂. + +## 1.2.2 第二个阶段(繁盛) +------- + +你可以从自己感兴趣的某个模块入手, 去阅读 Linux 内核代码. 这个过程也可以结合一些书籍来看, 特别是一些附带源码分析的书籍. 这对你对整个模块的体系和原理有一些深入的理解. 这个过程由浅入深. 1. 首先抓总概, 结合一些书籍和博客等的内容, 去阅读代码, 要对整个内核各个模块的思路和框架有一个比较清楚的认知. 这里推荐看陈莉君老师的 《Linux内核设计与实现》. 这个阶段完成后, 我们的小树芽已经开始成长, 成长为一颗颗小树苗, 依旧不繁盛, 但是已经有了自己的树干, 一些枝叶, - 2. 接着抠细节, 这个阶段, 针对某个单独的模块, 某个单独的特性, 结合书籍的内容, 精读代码, 不要只是看懂代码的实现, 要多思考为什么这么设计. 遇到想不通的问题, 多问, 多想. 不要放过一些关键的细节. 这个阶段辅助看一些附带内核源代码注解的书籍, 帮助自己理解. 比如《深入理解 linux 内核》、《奔跑吧 Linux 内核》、《深入linux内核架构》、《linux内核源代码情景分析》等. 这个阶段完成后, 我们的小树苗已经长大了, 枝繁叶茂, 能够撑起自己的一小片天地. 3. 实践是检验真理的为一真谛, 也是你巩固知识的必走途径. 这个阶段, 看到不懂的, 没想明白的, 多做一些实验, 多码一些代码, 看现象, 分析流程. 这样会让你对特性的理解更深刻, 细节也更清楚. 必走途径. 这个阶段, 看到不懂的, 没想明白的, 多做一些实验, 多码一些代码, 看现象, 分析流程. 这样会让你对特性的理解更深刻, 细节也更清楚. 这个阶段完成后, 我们的小树苗已经是一颗大树, 有了自己的一片天地, 可以遮风挡雨(定位问题, 解决BUG). -4. 随着这个阶段的不断深入, 我们可以找一些项目练手, 找一些内核相关的开源项目. 通过项目我们将了解更多的细节. 有了这些项目的加持, 我们的大树, 枝叶将更加繁盛. +4. 3 过程中对某个特性, 一定多翻阅邮件列表中对该特性的讨论, 同时要多看 git log 的历史. ①一个特性合入主线往往是经历了多个版本的, 而越早期的讨论, 对设计方案上的讨论可能更多. 甚至有一些讨论是在相关联的补丁中. 因此翻阅邮件列表的讨论会让你了解为什么这么设计, 以及设计方案的更多细节. ②一个特性自合入后, 不可能一成不变, 或 bugfix、或优化、或重构, 翻阅 git log 历史, 查看该特性的相关修改, 相关合入, 能让你对该特性有一个更全面的认识. -5. 从最感兴趣的模块看起, 将这颗树苗培养成大树之后, 以这颗树为根基, 逐渐扩展到其他模块, 内核的设计思想和理念很相似, 而且很多模块之间剪不断理还乱的联系, 有了这颗大树作为根基, 可以庇护我们了解更多的模块吗, 将其他树苗也培育成参天大树. 然后不断循环往复 2.1, 2.2, 2.3 节的内容. 第二个阶段的目标是, 对所学习的内核模块的实现逻辑有一个清晰的认知. 并且知道整个模块内部的框架, 以及它在整个内核中所处的位置和作用. 当这个阶段不断的往复, 我们将会有一颗最繁茂的大树, 然后伴随着其他繁盛的树木. +5. 随着这个阶段的不断深入, 我们可以找一些项目练手, 找一些内核相关的开源项目. 通过项目我们将了解更多的细节. 有了这些项目的加持, 我们的大树, 枝叶将更加繁盛. -6. 这个阶段, 主要是一些代码细节和代码细节的掌控和理解, 并且通过一些开发实战, 巩固自己的知识. +6. 从最感兴趣的模块看起, 将这颗树苗培养成大树之后, 以这颗树为根基, 逐渐扩展到其他模块, 内核的设计思想和理念很相似, 而且很多模块之间剪不断理还乱的联系, 有了这颗大树作为根基, 可以庇护我们了解更多的模块吗, 将其他树苗也培育成参天大树. 然后不断循环往复 2.1, 2.2, 2.3 节的内容. 第二个阶段的目标是, 对所学习的内核模块的实现逻辑有一个清晰的认知. 并且知道整个模块内部的框架, 以及它在整个内核中所处的位置和作用. 当这个阶段不断的往复, 我们将会有一颗最繁茂的大树, 然后伴随着其他繁盛的树木. + +7. 这个阶段, 主要是一些代码细节和代码细节的掌控和理解, 并且通过一些开发实战, 巩固自己的知识. 关于本章的内容, 我 GitHub 和 CSDN 都有汇总, 也在不断完善和更新. @@ -49,36 +117,47 @@ Linux 内核特性演进史 * [Linux进程管理与调度-之-目录导航_OSKernelLAB-CSDN博客](https://kernel.blog.csdn.net/article/details/51456569) ​ -## 1.3 根基(本章的重点内容) +## 1.2.3 根基(本章的重点内容) ------- -最后第三个阶段(根基), 通过 2 阶段学习, 你已经对代码的实现有一个比较深刻的认识. 在这个阶段我们不光要知道内核当前的设计, 知道它为什么这么设计, 更要清楚他之前还有哪些设计, 之前的设计存在哪些缺陷, 现在的设计解决了哪些问题, 又存在哪些问题. +通过第二个阶段学习, 你已经对代码的实现有一个比较深刻的认识. 在学习的过程中我们不光要知道内核当前的设计, 知道它为什么这么设计, 更要清楚他之前还有哪些设计, 之前的设计存在哪些缺陷, 现在的设计解决了哪些问题, 又存在哪些问题. -1. 这个阶段的目标是, 让你对各个模块有一个全局的把握. 第二个阶段你已经知道内核的具体实现了, 这个阶段, 我们不光了解到的是整个内核特性演进的历史和现状, 更对所关注模块的发展方向, 优化方向, 会有一个全局的把控. 我们的知识将更加系统, 构成一个知识体系. 在这个阶段, 我们的大树的根会越扎越深, 深入到整个森林土壤的最深处, 亘古不变. +在第二个阶段的学习过程中, 一定要善于总结. 这就是我们现在想要说的内容, 这个严格其实来说不能作为一个单独阶段, 因为这个总结的过程应该发生在第二个阶段学习的过程中. 但是它是那么重要, 以至于我们有必要把它拿出来单独讲. -2. 社区有很多 Maintainer, 我们跟他们的差距不光是编码水平上的, 更是历史的. 这些 Maintainer 大多数都是在内核早期开发过程中, 不断开发, 不断演进的过程中实战出来的. 他们懂的, 不光是当前的代码实现, 他们更清楚历史上的一些问题. 所以他们对内核整个模块有一个清晰的脉络, 更对这个模块的发展和演进, 有一个清楚的认知. 而这些我们是欠缺的, 也正是我们需要补齐的. 当然跟 Maintainer 肯定会有差距, 但是至少对我们的眼界会十分有益. +1. 第二个阶段我们了解了代码实现, 并很多细节, 同时也通过实践让自己的知识更扎实. 但是他们仍然还没有形成体系. 我们逐渐爬过了树木的每个枝杈, 走过了每个路径. 但是指到每个枝杈上我们可以看到细节, 但是没有一个全局的把握. 通过总结我们把知识点串联起来, 形成一个网. 而这个树木也在我们脑子里面形成了一个图像, 我们知道它总体的样子, 知道它每个枝杈的位置和形状, 知道每个果实的大小和位置. -3. 这个阶段可以跟踪下社区的进展, 内核代码是在不断发展和演进的, 要带着发展的眼光看, 时刻关注社区的动向. 完善和丰富我们的知识体系. 这些信息可以通过关注社区邮件列表、kernelnewbies 和 LWN 来获取. +2. 这个阶段的目标是, 让你对各个模块有一个全局的把握. 第二个阶段你已经知道内核的具体实现了, 这个阶段, 我们不光了解到的是整个内核特性演进的历史和现状, 更对所关注模块的发展方向, 优化方向, 会有一个全局的把控. 我们的知识将更加系统, 构成一个知识体系. 在这个阶段, 我们的大树的根会越扎越深, 深入到整个森林土壤的最深处, 亘古不变. -[LinuxVersions - Linux Kernel Newbies](https://kernelnewbies.org/LinuxVersions) +3. 社区有很多 Maintainer, 我们跟他们的差距不光是编码水平上的, 更是历史的. 这些 Maintainer 大多数都是在内核早期开发过程中, 不断开发, 不断演进的过程中实战出来的. 他们懂的, 不光是当前的代码实现, 他们更清楚历史上的一些问题. 所以他们对内核整个模块有一个清晰的脉络, 更对这个模块的发展和演进, 有一个清楚的认知. 而这些我们是欠缺的, 也正是我们需要补齐的. 当然跟 Maintainer 肯定会有差距, 但是至少对我们的眼界会十分有益. + + +## 1.2.4 历史的眼光和发展的眼光 +------- + +要带着发展的眼光看内核代码,你现在看到的代码是这个样子的。 + +* 那它历史上可不一定是这样子的,需要你去回顾它。 + +* 它以后也不一定还是它现在的样子,需要你去不断的关注。 + + +1. 这个阶段可以跟踪下社区的进展, 内核代码是在不断发展和演进的, 要带着发展的眼光看, 时刻关注社区的动向. 完善和丰富我们的知识体系. 这些信息可以通过关注社区邮件列表、kernelnewbies 和 LWN 来获取. + + [LinuxVersions - Linux Kernel Newbies](https://kernelnewbies.org/LinuxVersions) ​ - -[Kernel coverage at LWN.net](https://lwn.net/Kernel) + [Kernel coverage at LWN.net](https://lwn.net/Kernel) ​ +2. 关于已经合入的特性的历史信息, 同样可以从邮件列表的归档记录和 Patchwork 等地方获取. 主线合入的内核的特性, 往往都是通过不断的改进, 经过了 N 轮重构和 review 才合入的主线, 而越早期的讨论, 涉及的内容可能更多, 也更容易大家理解. 对于一些特性, 不理解它为什么这么实现的时候, 去找当时社区邮件列表的讨论, 往往是最直接有效的途径. -4. 关于已经合入的特性的历史信息, 同样可以从邮件列表的归档记录和 Patchwork 等地方获取. 主线合入的内核的特性, 往往都是通过不断的改进, 经过了 N 轮重构和 review 才合入的主线, 而越早期的讨论, 涉及的内容可能更多, 也更容易大家理解. 对于一些特性, 不理解它为什么这么实现的时候, 去找当时社区邮件列表的讨论, 往往是最直接有效的途径. - - -[Project List - Patchwork](https://patchwork.kernel.org) + [Project List - Patchwork](https://patchwork.kernel.org) ​ - -[Linux Kernel Mailing List](https://lore.kernel.org/patchwork/project/lkml/list) + [Linux Kernel Mailing List](https://lore.kernel.org/patchwork/project/lkml/list) ​ - -[lkml.org](https://lkml.org/lkml) + [lkml.org](https://lkml.org/lkml) -本章的内容, 就是为了帮助大家构建第 3 阶段的知识体现, 有了这个知识体系, 我们再继续第 2 阶段的过程中, 会更加融会贯通. +博客本章以及其展开的内容, 就是为了帮助大家构建内核的知识体现,了解内核各个模块的前世今生, 有了这个知识体系, 我们在不断继续第 2 阶段的学习迭代时, 会更加融会贯通. + 本章的内容, 将不断更新 : * 采用 TOPDOWN 自顶向下的学习方法, 从每个内核子模块入手, 将每个子模块不断细化. 完善整个内核的技能树. @@ -87,7 +166,8 @@ Linux 内核特性演进史 * 不管跟进社区最新的进展; -由于工作的原因, 更新可能不会太快, 但是我有时间就会写. +> 由于工作的原因, 更新可能不会太快, 但是我有时间就会写. + # 2 Linux 内核特性演进史 -------