为什么要阅读Linux内核源码以及如何阅读Linux内核源码
阅读源码目的:为了更好地编写驱动程序;对自己写的程序有更深入的理解;并且自己的岗位定位在底层开发。
Linux内核阅读方法
阅读linux内核,常用下面两种方法: bochs+linux0.11+书(linux内核完全注释、linux内核完全剖析、linux内核设计的艺术) Source Insight+linux2.X+书(linux内核情景分析) 另外:笨叔叔近两年出的两本书不错,《奔跑吧Linux内核 入门篇》和《奔跑吧Linux内核 》基于Linux4.x,只是配套视频有点贵,但是书写的很不错,以实际问题出发,在实际工作中很有用。 阅读源码分为纵向阅读和横向阅读。纵向就是跟着内核的执行流程来读,横向就是按照内核的各大功能模块来读。 第一种方法纵向或者横向来读都可以,因为代码量不是很大。《linux内核完全剖析》《linux内核完全注释》是引导你横向阅读的书,《linux内核设计的艺术》是引导你纵向阅读的书。建议横向纵向结合着来,纵向跟着bochs调试工具来是必不可少的,当遇到问题时进入到相应的功能模块横向拓展一下。
《linux内核情景分析》中的内核版本是2.4.X,现代内核版本还是推荐横向阅读,纵向几乎不可能。(在Linux下搭建了quem虚拟机,然后用GDB调试内核也可以)总之阅读源码的方法也就上面两种,贵在坚持,但是别闭门N久学内核,没有意义。而且长时间只读代码,不敲代码是不行的。
如果想在简历中写上关于Linux内核的经验,先不要花大量时间看源码,先把《linux内核设计与实现》读了,在找工作中更有用。
Linux5.8.14
通常Linux会有以下目录 arch 子目录包括所有和体系结构相关的核心代码。它还有更深的子目录,每一个代表一种支持的体系结构
include 子目录包括编译核心所需要的大部分 include 文件。它也有更深的子目录,每一个支持的体系结构一个。include/asm 是这个体系结构所需要的真实的 include 目录的软链接,例如 include/asm-i386 。为了改变体系结构,你需要编辑核心的 makefile ,重新运行 Linux 的核心配置程序
init 这个目录包含核心的初始化代码,这时研究核心如何工作的一个非常好的起点
mm 这个目录包括所有的内存管理代码。和体系结构相关的内存管理代码位于 arch/*/mm/
drivers 系统所有的设备驱动程序在这个目录。它们被划分成设备驱动程序类
ipc 这个目录包含核心的进程间通讯的代码
modules 这只是一个用来存放建立好的模块的目录
fs 所有的文件系统代码。被划分成子目录,每一个支持的文件系统一个
kernel 主要的核心代码。同样,和体系相关的核心代码放在 arch/*/kernel
net 核心的网络代码
lib 这个目录放置核心的库代码。和体系结构相关的库代码在 arch/*/lib/
scripts 这个目录包含脚本(例如 awk 和 tk 脚本),用于配置核心
按照以下顺序阅读源代码会轻松点 核心功能(kernel)
内存管理(mm)
文件系统(fs)
进程通讯(ipc)
网络(net)
系统启动和初始化(init/main和head.S)
其他等等
操作系统/Linux 内核 中断:介绍中断的作用,要是再能从硬件、汇编级别去介绍一下中断会发生什么就更棒了 信号:几乎所有讲操作系统的书都有介绍信号,linux信号参阅《Unix环境高级编程》第10章:信号,以及《深入理解linux内核》第11章:信号,需要了解可靠信号与不可靠信号的区别,还需要特别了解SIGCHLD、SIGCLD信号 进程与线程:轻量级进程、系统级线程、用户级线程、进程,这些可以读linux内核源码以及一些资料很容易理解,协程(Python中yield的效果以及它的具体实现(C源码)了解一下),可以去网上找找CPP的协程库去读一读 linux常见的调度算法:知道这些算法的思想就行,读个linux源码就更棒 linux文件系统:《深入理解linux内核》第12章:虚拟文件系统 以及 第18章:Ext2和Ext3文件系统 以及 第16章:访问文件,可以让你深入了解linux文件系统 linux IPC:System V、Posix IPC熟悉一下,可以参阅《Unix环境高级编程 进程间通信》,以及清楚它们的作用与优缺点,当然还是推荐去阅读一下IPC的linux内核源码 如何实现linux的高并发,线程池的思想:github上有好多好多线程库,抓一个下来自己读一读,代码量不是很大,很推荐自己动手写一写 死锁产生的四个必要条件及如何预防 编写linux的并发测试程序:生产者消费者并发程序要求能够写得出来 惊群效应:举例子讲一下惊群现象,然后去了解一下如何避免。内核中存在两个惊群的例子,accept惊群与epoll惊群,linux内核经过改进避免了一些惊群,可以从内核源码去解释一下它是怎么做的 fork、vfork、clone的区别:这个真的只能读源码才能深入了解了,注意,phtread线程库就是使用的clone 僵尸进程:清楚一下概念以及它的危害,然后知道如何去避免僵尸进程 select、poll、epoll的区别:从内核源码去分析,select与poll实现差不多,读了一个源码差不多很快就能读懂第二个,epoll设计很独特也很有意思,赶快去读一读 linux内核伙伴系统、slab缓存(实现原理、与普通内存分配的区别以及优势):简单介绍参阅《深入理解linux内核》第8章:内存管理,深入了解就去读linux内核源码…
1、Linux核心源程序通常都安装在/usr/src/linux下,而且它有一个非常简单的编号约定:任何偶数的核心(的二个数为偶数,例如 2.0.30)都是一个稳定地发行的核心,而任何奇数的核心(例如2.1.42)都是一个开发中的核心。
2、核心源程序的文件按树形结构进行组织,在源程序树的最上层,即目录/usr/src/linux下有这样一些目录和文件。
◆ COPYING: GPL版权申明。对具有GPL版权的源代码改动而形成的程序,或使用GPL工具产生的程序,具有使用GPL发表的义务,如公开源代码。
◆ CREDITS: 光荣榜。对Linux做出过很大贡献的一些人的信息。
◆ MAINTAINERS: 维护人员列表,对当前版本的内核各部分都有谁负责。
◆ Makefile: 第一个Makefile文件。用来组织内核的各模块,记录了个模块间的相互这间的联系和依托关系,编译时使用;仔细阅读各子目录下的Makefile文件 对弄清各个文件这间的联系和依托关系很有帮助。
◆ ReadMe: 核心及其编译配置方法简单介绍。
◆ Rules.make: 各种Makefilemake所使用的一些共同规则。
◆ REPORTING-BUGS:有关报告Bug 的一些内容。
● Arch/ :arch子目录包括了所有和体系结构相关的核心代码。它的每一个子目录都代表一种支持的体系结构,例如i386就是关于intel cpu及与之相兼容体系结构的子目录。PC机一般都基于此目录;
● Include/: include子目录包括编译核心所需要的大部分头文件。与平台无关的头文件在 include/linux子目录下,与 intel cpu相关的头文件在include/asm-i386子目录下,而include/scsi目录则是有关scsi设备的头文件目录。
● Init/: 这个目录包含核心的初始化代码(注:不是系统的引导代码),包含两个文件main.c和Version.c,这是研究核心如何工作的好的起点之一。
● Mm/:这个目录包括所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等;而和体系结构相关的内存管理代码则位于arch//mm/,例如arch/i386/mm /Fault.c。
● Kernel/:主要的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同样,和体系结构相关的代 码在arch//kernel中。
● Drivers/: 放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目录:如,/block 下为块设备驱动程序,比如ide(ide.c)。如果你希望查看所有可能包含文件系统的设备是如何初始化的,你可以看drivers/block /genhd.c中的device_setup()。它不仅初始化硬盘,也初始化网络,因为安装nfs文件系统的时候需要网络。
● Documentation/: 文档目录,没有内核代码,只是一套有用的文档,可惜都是English的,看看应该有用的哦。
● Fs/: 所有的文件系统代码和各种类型的文件操作代码,它的每一个子目录支持一个文件系统, 例如fat和ext2。
● Ipc/: 这个目录包含核心的进程间通讯的代码。
● Lib/: 放置核心的库代码。
● Net/: 核心与网络相关的代码。
● Modules/: 模块文件目录,是个空目录,用于存放编译时产生的模块目标文件。
● Scripts/: 描述文件,脚本,用于对核心的配置。
一般,在每个子目录下,都有一个 Makefile 和一个Readme 文件,仔细阅读这两个文件,对内核源码的理解很有用。
对Linux内核源码的分析,有几个很好的入口点:一个就是系统的引导和初始化,即从机器加电到系统核心的运行;另外一个就是系统调用,系统调用是用 户程序或操作调用核心所提供的功能的接口。对于那些对硬件比较熟悉的爱好者,从系统的引导入手进行分析,可能来的容易一些;而从系统调用下口,则可能更合 适于那些在dos或Uinx、Linux下有过C编程经验的高手。
建议书籍说明(参考):
1, 《Linux内核设计与实现》,英文名Linux Kernel Development(所以有人叫它LKD),机械工业出版社,美国Robert Love著,陈莉君译者。评说: 此书是当今首屈一指的入门最佳图书。作者是为2.6内核加入了抢占的人,对调度部分非常精通,而调度是整个系统的核心,因此本书是很权威的。这本书讲解浅显易懂,全书没有列举一条汇编语句,但是给出了整个Linux操作系统2.6内核的概观,使你能通过阅读迅速获得一个overview。而且对内核中较为混乱的部分(如下半部),它的讲解是最透彻的。对没怎么深入内核的人来说,这是强烈推荐的一本书。
2, 《Linux内核源代码情景分析》上、下。毛德操、胡希明著,浙江大学出版社,评说: 本书是基于2.4.0内核的。上册讲解内存管理、中断、异常与系统调用、进程控制、文件系统与传统Unix IPC;下册讲解socket、设备驱动、SMP和引导。关于这套书的评价褒贬不一,我个人认为其深度是同类著作中最优秀的。本书基于Intel IA32体系,由于厚度大,很多体系上的知识都捎带讲解了,所以如果你想深入了解内核的工作机制而又不非常熟悉Intel CPU的体系构造,本书是最合适的。缺点是:版本较老,没有TCP/IP协议栈部分(它讲的socket只是Unix域协议的),图表太少,不适合初学者入门。还有就是对学生朋友来说,可能书价偏高,这样的话可以考虑先买上册,因为上册是核心部分,下册一大部分都在讲具体PCI/ISA/USB设备的驱动。
3, 《深入理解Linux内核》第二版。中国电力出版社。也是陈莉君译。此书是Linux内核黑客在推荐图书时的首选。评说: 此书图表很多,形象地给出了关键数据结构的定义,与《情景分析》相比,本书内容紧凑,不会一个问题讲解动辄上百页,有提纲挈领的功用,但是深度上要逊于《情景分析》。
4, 其它的几本书。市面上能见到的其它的Linux内核的图书,《Linux设备驱动程序》、《Linux内核源代码完全注释》以及新出的《Linux内核分析及编程》等。 《Linux设备驱动程序》第二版是基于2.4的,中文翻译不错,中国电力出版。这书强调动手实践,但它是讲解“设备驱动”的,不是最核心的东西,而且有些东西没硬件的话无法实践,可能更适合驱动开发的程序员吧,不太适合那些For fun and profit的人。此书有第三版英文版,东南大学出版社影印,讲解2.6的,行文流畅,讲解的面也比第二版更广泛,我读过其中关于同步与互斥、内存分配的部分,感觉很不错。 《Linux内核源代码完全注释》(机械工业出版社)是同济大学的博士生赵炯的著作,讲解0.1Linux内核,我没买也没看,有看过的朋友说一说。 《Linux内核分析及编程》(电子工业出版社)是刚刚出版的,国人写的,讲解2.6.11 。很多人说好,但有人说不够系统,我没买,不敢评说。 还有一本清华出的《Linux内核编程指南(第三版)》,原书应该是好书,但是翻译、排版十分糟烂,脱字跳行,根本没法看,我买了一本又扔掉了。
5, 其它资源。TLDP(The Linux Documentation Project)有大量文档,其中不少是关于内核的,有些是在国外出版过的,像《Linux Kernel Interls》《The Linux Kernel》《Linux Kernel Module Programming Guide》等,作者都是亲身参加开发的人,著作较为可信。
6, 一本不是讲解Linux的书:《现代体系结构上的Unix系统:内核程序员的SMP和Caching技术》,人民邮电出版社2003版, 本书虽然不是讲解Linux,但是对所有Unix内核都是适用的,适合对SMP和CPU的Cache这些组成原理知识不是很熟的朋友,而且是很多国外牛人推荐的书。中文版翻译非常负责。
参考资料
Linux内核源码:https://www.kernel.org/
Github Linux内核 https://github.com/torvalds/linux
在线阅读Linux内核源码网站:https://elixir.bootlin.com/linux/latest/source