一、内核行数
Linux内核分为CPU调度、内存管理、网络和储存四大子系统,针对硬件的驱动成百上千。代码的数目更是大的惊人。
先谈谈最早的内核linux0.11,下边这本书可以说好多驱动工程师都学习过,我花了大约1个半月,勉强看了一遍。
再来看看内核代码量的统计。
2020年1月1日linux是什么系统,Linux内核Git源码树中的代码达到了2780万行。
phoronix网站统计了Linux内核在步入2020年时的一些源码数据并作了总结。
从统计数据来看,Linux内核源码树共有:
27852148行(包括文档、Kconfig文件、树中的用户空间实用程序等)、
887925次commit
21074位不同的作者
2780万行代码分布在66492个文件中。
Linux内核从最初的10000行代码到现今的2780万行代码就是全球精英共同贡献的结果。
根据三天一万行的速率,也须要2700天,也须要7年多。
这还是构建在所有单次都认识,
所有代码逻辑看了的都懂,
但是都不忘掉的基础上。
实际上虽然我们真的看完了,
几年后内核又会有特别大的变化,
可以说一辈子都看不完Linux内核的代码。
Linux内核Git源码树中的代码达到了2780万行,核心代码只有2%是由李纳斯•托瓦兹自己编撰的,其他均是其他个人和组织贡献的,李纳斯•托瓦兹公开了Linux但保留了选择新代码和须要合并的新方式的最终判决权。
不仅LinusTorvalds,对内核贡献最多的是DavidS.Miller、MarkBrown、TakashiIwai、ArndBergmann、AlViro和MauroCarvalhoChehab。
而参与贡献的公司,从域名统计来看,微软、Intel与RedHat排在了最前列。
二、内核目录文件大小
但是,现今的内核早已膨胀的不成样子了,以还不算最新的linux-4.1.15为例:
整个内核源码一共约793M:
驱动代码占了大约一半,大概380M:
体系相关的代码大概134M:
网路子系统相关的代码26M:
文件系统相关的代码37M:
linux内核核心代码大概6.8M:
这种目录任意一个目录想完全看明白都十分不容易。
内核源码获取
最新源码离线下载:
一个在线浏览的内核源码网站(可以浏览2.6.11~latest的源码):
三、内核子系统
哪些是内核:
在计算机科学中是一个拿来管理软件发出的数据I/O(输入与输出)要求的计算机程序,将那些要求转译为数据处理的指令并交由中央处理器(CPU)及计算机中其他电子组件进行处理,是现代操作系统中最基本的部份。
它是为诸多应用程序提供对计算机硬件的安全访问的一部份软件,这些访问是有限的,并由内核决定一个程序在哪些时侯对某部份硬件操作多长时间。
linux内核代码涉及知识点包括汇编指令、c语言、硬件组成原理、操作系统、数据结构和算法、各种外设总线、驱动、网络合同栈。
直接对硬件操作是十分复杂的。所以内核一般提供一种硬件具象的方式,来完成这种操作。
通过进程间通讯机制及系统调用,应用进程可间接控制所需的硬件资源(非常是处理器及IO设备)。
最前面是用户(或应用程序)空间。这是用户应用程序执行的地方。用户空间之下是内核空间,Linux内核正是坐落这儿。
GNUCLibrary(glibc)也在这儿。它提供了联接内核的系统调用插口,还提供了在用户空间应用程序和内核之间进行转换的机制。
内核和用户空间的应用程序使用的是不同的保护地址空间。
每位用户空间的进程都使用自己的虚拟地址空间,而内核则占用单独的地址空间。
Linux内核可以进一步界定成3层。最前面是系统调用插口,它实现了一些基本的功能,比如read和write。
系统调用插口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码。这种代码是Linux所支持的所有处理器体系结构所通用的。
在这种代码之下是依赖于体系结构的代码,构成了一般称为BSP(BoardSupportPackage)的部份。这种代码用作给定体系结构的处理器和特定于平台的代码。
内核主要系统包括:SCI:系统调用插口PM:进程管理VFS:虚拟文件系统MM:显存管理NetworkStack:内核合同栈Arch:体系构架DD:设备驱动
1系统调用插口
SCI层提供了个别机制执行从用户空间到内核的函数调用。这个插口依赖于体系结构,甚至在相同的处理器家族内也是这么。
SCI实际上是一个十分有用的函数调用多路复用和多路分解服务。
在./linux/kernel中您可以找到SCI的实现,并在./linux/arch中找到依赖于体系结构的部份。
2进程管理
进程管理的重点是进程的执行。
在内核中,这种进程称为线程,代表了单独的处理器虚拟化(线程代码、数据、堆栈和CPU寄存器)。
在用户空间,一般使用进程这个术语,不过Linux实现并没有分辨这两个概念(进程和线程)。
内核通过SCI提供了一个应用程序编程插口(API)来创建一个新进程(fork、exec或PortableOperatingSystemInterface[POSIX]函数),停止进程(kill、exit),并在它们之间进行通讯和同步(signal或则POSIX机制)。
3显存管理
内核所管理的另外一个重要资源是显存。为了提升效率,倘若由硬件管理虚拟显存,显存是根据所谓的显存页形式进行管理的(对于大部份体系结构来说都是4KB)。
Linux包括了管理可用显存的方法,以及化学和虚拟映射所使用的硬件机制。
4虚拟文件系统
虚拟文件系统(VFS)是Linux内核中十分有用的一个方面,由于它为文件系统提供了一个通用的插口具象。VFS在SCI和内核所支持的文件系统之间提供了一个交换层。
在VFS里面,是对例如open、close、read和write之类的函数的一个通用API具象。在VFS下边是文件系统具象,它定义了下层函数的实现方法。
它们是给定文件系统(超过50个)的插件。文件系统的源代码可以在./linux/fs中找到。
文件系统层之下是缓冲区缓存,它为文件系统层提供了一个通用函数集(与具体文件系统无关)。
这个缓存层通过将数据保留一段时间(或则随后预先读取数据便于在须要是就可用)优化了对化学设备的访问。缓冲区缓存之下是设备驱动程序,它实现了特定化学设备的插口。
5网路堆栈
网路堆栈在设计上依循模拟合同本身的分层体系结构。
回想一下,InternetProtocol(IP)是传输合同(一般称为传输控制合同或TCP)下边的核心网路层合同。TCP里面是socket层,它是通过SCI进行调用的。
socket层是网路子系统的标准API,它为各类网路合同提供了一个用户插口。
从原始帧访问到IP合同数据单元(PDU),再到TCP和UserDatagramProtocol(UDP),socket层提供了一种标准化的方式来管理联接,并在各个终点之间联通数据。内核中网路源代码可以在./linux/net中找到。
6设备驱动程序
Linux内核中有大量代码都在设备驱动程序中,它们就能运转特定的硬件设备。
Linux源码树提供了一个驱动程序子目录,这个目录又进一步界定为各类支持设备,比如Bluetooth、I2C、serial等。设备驱动程序的代码可以在./linux/drivers中找到。
下边这个图形象的讲解了Linux内核都有什么东西!
四、如何学习内核?1.学习主线
linux内核源码大而全,一个人,虽然再聪明、再有精力,也不可能完全看完、看懂所有的linux内核源码。
一口君建议根据以下主线进行深入研究:
顺着某一个主线,深入进去,在研究清楚这个主线的同时,向其他的主线扩充、渗透和学习。
此处之所以将驱动列为学习内核的入口,是由于内核为好多外设驱动实现了构架,例如I2C、SPI、UART、PCIE、字符设备、网络设备、块设备,我们可以从最基本的字符设备学起,学习怎么编撰一个简单的模块学习怎么怎么为一些简单的设备例如LED、KEY、ADC等编撰驱动可以说驱动是我们学习内核最简单的入口,
由点到线、由线到面、由面到体,层层深入、不断精进,是学习linux内核源码的一个有效的方式。
2.代码阅读工具
对于代码阅读技巧从两个角度来介绍linux内核源代码结构,一个方面是须要选择一个比较有效阅读代码的工具。
一口君强烈推荐:sourceinsight这款阅读代码利器!
也可以使用vscode或则vim+ctags的组合。
不过一口君十几年的从业经验,
99%以上的开发人员都选择SI阅读内核代码。
代码并不是献给人看的,而是交给机器运行的。
所以我们去理解他人的代码时,并不能像看小说一样去通篇的阅读代码,而应当是像研究化石一样去调查它,揭秘它。
有时我们常常也须要把对方的一段代码亲手的实现一遍,之后自己举一反三看自己会如何去实现它,就能真正的理解。
3.学习的内核版本
有些人推荐先阅读一些低版本的内核,例如0.01版的,总代码量才1万行左右。
阅读这个代码大约一个月应当能比较清晰了。
然而linux内核源代码结构,改代码与现今的代码差别巨大,阅读后可以理解基本思想,但对理解现有代码的帮助不是非常显著。
3.10版本以后的内核都支持设备树!
所以一口君建议是尽量选择3.10版本以后的代码阅读学习。
4.学习Linux最重要的是培养自己写代码的能力和对Linux框架结构的了解
Linux内核中绝大部份代码都是由这个月球上顶级的技术大牛所编撰,
这种代码的高内聚低耦合,
其精准度,简约度、质量都相当的高,
时常见到一段高质量的代码linux命令详解词典,
一口君就会被那一行行无趣的代码背后隐藏的设计思想所震憾,所吓倒!
阅读内核的代码简直就是在欣赏艺术品!
好多粉丝问我怎么提升自己的C语言编程水平,一口君不厌其烦的重复着同样一句话:看Linux内核!
代码中自由颜如玉!代码中自有黄金屋!
时刻保持激情,任性和耐性!
从量变到质变!
水滴石穿!
愿诸位都还能熟练把握Linux
-EOF-