概述
在开始今天的内容之前,其实有一些题外话可以和大家分享一下。自从工作以来,我个人一直都有一个观点。那就是怎么样利用简单的代码来说明开发中的问题,或者是解释软件中的原理,这是一个很高的学问。有些道理看上去云里雾里说不清楚,其实都可以通过编写代码来验证的.os可以、cpu可以、cache可以、编译器可以、网络协议也可以,很多很多的内容完全可以通过几行代码就可以表达得非常清楚,但是事实上我们并没有这么做。
我想原因无非是这么几条,
一来授业者对相关知识的学习也是停留在概念上而已;
二来我们的学习过于死板和教条、太关注知识、不求实践;
三就是学习者自身缺少思考的能力、缺少自我反省的能力、对很多东西不求甚解。
而学习Linux内核就能很好的帮助我们解决这些问题。
Linux内核学习路线:
以网络协议栈为例:
1、Linux内核源代码结构
Linux 的内核源代码可以从 https://www.kernel.org/网站上下载,Linux-4.1.2以上的版本(含)。 其代码目录结构如下:
-
Documentation:这个目录下面没有内核的代码,有一套有用的内核文档。其中文档质量良莠不齐,有很多内核文档的质量很优秀并且相当完整,例如文件系统;但是有的则完全没有文档,例如进程调度。在这个目录里不时可以发现有用的东西。
-
arch:此目录下的所有子目录的东西都是体系结构特有的代码。
-
drivers:内核的驱动程序代码。此部分的代码占内核代码的大部分,包括显卡、网卡、PCI 等外围设备的驱动代码。
-
fs:文件系统代码。包含 ext2、ext3、ext4 等本地文件系统,CD-ROM、isofs 等镜像系统,还有 NFS 等网络文件系统,以及 proc 等伪文件系统。
-
include:此目录中包含了 Linux 内核中的大部分头(*.h)文件。
-
init:内核初始化过程的代码。
-
ipc:进程间通信代码。
-
kernel:这部分是 Linux 内核中最重要的,包含了内核中平台无关的基本功能,主要包含进程创建、销毁和调度的代码。
-
lib:此目录中主要包含内核中其他模块使用的通用函数和内核自解压的函数。
-
mm:此目录中的代码实现了平台无关的内存管理代码。
-
scripts:此目录下是内核配置时使用的脚本,当使用 make menuconfig 或者 make xconfig 命令时,会调用此部分代码。
-
net:此目录中包含 Linux 内核的网络协议栈的代码。在子目录 netfilter 下为 netfilter的实现代码,netfilter 构建了一个框架,允许在不重新编译内核的情况下,编写可加载内核,在指定的地方插入回调函数,以用户自己的方式处理网络数据。子目录 ipv4 和 ipv6 为 TCP/IP 协议栈的 IPv4 和 IPv6 的实现,主要包含了 TCP、UDP、IP 协议的代码,还有 ARP 协议、ICMP 协议、IGMP 协议、netfilter 的 TCP/IP 实现等代码实现,以及如 proc、ioctl 等控制相关的代码。
组织代码另一个表现形式就是映射到Linux代码的3个内核层:
2、内核中网络剖析流程
网络协议栈是由若干个层组成的,网络数据的流程主要是指在协议栈的各个层之间的传递。在前面章节中TCP 网络编程的流程,一个 TCP 服务器的流程按照建立 socket()函数,绑定地址端口 bind()函数,侦听端口 listen()函数,接收连接 accept()函数,发送数据send()函数,接收数据 recv()函数,关闭 socket()函数的顺序来进行。与此对应内核的处理过程也是按照此顺序进行的,网络数据在内核中的处理过程主要是在网卡和协议栈之间进行:从网卡接收数据,交给协议栈处理;协议栈将需要发送的数据通过网络发出去。
如下图所示,总结了各层间在网络输入输出时的层间调用关系。由图中可以看出,数据的流向主要有两种。应用层输出数据时,数据按照自上而下的顺序,依次通过插口层、协议层和接口层;当有数据到达的时候,自下而上依次通过接口层、协议层和插口层的方式,在内核层传递。
应用层 Socket 的初始化、绑定(bind)和销毁是通过调用内核层的 socket()函数进行资源的申请和销毁的。发送数据的时候,将数据由插口层传递给协议层,协议层在 UDP 层添加 UDP 的首部、TCP 层添加 TCP 的首部、IP 层添加 IP 的首部,接口层的网卡则添加以太网相关的信息后,通过网卡的发送程序发送到网络上。
接收数据的过程是一个相反的过程,当有数据到来的时候,网卡的中断处理程序将数据从以太网网卡的 FIFO 对列中接收到内核,传递给协议层,协议层在 IP 层剥离 IP 的首部、UDP 层剥离 UDP 的首部、TCP 层剥离 TCP 的首部后传递给插口层,插口层查询 socket 的标识后,将数据送给用户层匹配的 socket。
如下图所示为 Linux 内核层的网络协议栈的架构视图。最上面是用户空间层,应用层的程序位于此处。最底部是物理设备,例如以太网网卡等,提供网络数据的连接、收发。中间是内核层,即网络协议栈子系统。流经网络栈内部的是 socket 缓冲区(由结构 sk_buffs接连),它负责在源和汇点之间传递报文数据。
顶部(参见上图所示)是系统调用接口,它为用户空间的应用程序提供了一种访问内核网络子系统的接口。位于其下面的是一个协议无关层,它提供了一种通用方法来使用底层传输层协议。然后是实际协议,在 Linux 中包括内嵌的协议 TCP、UDP,当然还有 IP。然后是另外一个网络设备协议无关层,提供了与各个设备驱动程序通信的通用接口,最下面是设备驱动程序本身。
·····························
而这些内核笔记就是我给大家推荐的《Linux内核内存管理》训练营的随堂笔记,对内核的每一块技术进行抽丝剥茧的分析。
https://ke.qq.com/course/3485817?flowToken=1036017
训练营能解决我们Linux内核学习中的哪些问题?
1.大块内核内存怎么样分配? 2.伙伴系统如何申请内核内存? 3.slab分配器如何申请内核内存的? 4.vmalloc()申请的内存有什么特点? 5.用户程序使用malloc()申请到的内存空间在什么范围? 6.TLB中缓存的是什么内容? 7.虚拟内存如何组织的? 8.缺页机制是如何实现?
最后再提醒下,训练营限时特惠!
今天到手价0.02,原价198
课程永久有效,优惠就这两天,抓紧!
训练营课前预习资料包:
最后
以上就是鲜艳白猫为你收集整理的精心整理的Linux内核内存管理笔记的全部内容,希望文章能够帮你解决精心整理的Linux内核内存管理笔记所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复