mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-08-18 17:17:39 +08:00
description: readme
This commit is contained in:
@@ -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 内核特性演进史
|
||||
-------
|
||||
|
||||
Reference in New Issue
Block a user