linux源码目录结构

阿木木 阿木木 | 225 | 2022-12-09

为什么要分享内核的目录结构呢,因为内核过于庞大了,对于初次接触内核,往往会因为内核过于庞大望而却步,从入门到放弃。从1991年linus发布第一版的linux至今已经经过30年的发展了。全世界无数的开源贡献者对linux做出贡献,同样linux的代码量也从最初的1万行的数量级,达到现在的几千万行的数量级。而一个人能同一时刻读懂的代码量也就1万行左右。所以这么多代码是不可能细节到每一句都读懂的。如果阅读源码有正确的顺序和方法会事半功倍。这篇文章,描述一下linux的目录结构,对初学者阅读linux源码会有帮助。阅读的时候能抓住重点,进而顺藤摸瓜逐渐上手,找到自己的方法。

一 内核目录结构

通常我们下载一份linux的源码解压好源码之后目录结构如下:

.
├── arch//该目录下的代码和芯片架构相关,比如x86,mips,arm,arm64
├── block//块设备相关的一些common代码,驱动在drivers目录下
├── certs//加密标签相关的一些代码
├── crypto//加密相关的一些代码
├── Documentation//内核参考文档
├── drivers//该目录应该是最大的,也是裁剪最多的,各种驱动子系统和驱动代码
├── firmware//忽略
├── fs//各种文件系统的框架部分代码,驱动在drivers目录下
├── include//按照功能分类的系统的一些头文件,
├── init//系统初始化的common部分代码
├── ipc//消息队列,系统调用,信号量等的common部分代码
├── kernel//内核里面最核心的base代码
├── lib//从名字可以看出来,是其他地方会使用到的一些公共代码
├── mm//内存管理部分的common代码
├── net//网络协议栈的公共代码,重点在协议,网卡驱动在drivers目录下
├── samples//各个子系统的使用例子代码,初学者可以做参看
├── scripts//编译内核的时候会用到一些辅助工具和脚本,在该目录下,以及反汇编调试内核工具
├── security//系统安全相关的一些代码
├── sound//声卡相关的代码alsa等
├── tools//内核提供的一些小工具,主要是操作内核提供的节点之类的比如/dev/xxx
├── ubuntu//ubuntu用到的部分代码
├── usr//内核编译用到的一个工具的代码
└── virt///kvm用到的部分代码
上面的目录是内核解压后的完整的目录,每一个目录下还没有不止一级。对于初次接触linux的可以重点关注下面的目录

1),arch:根据硬件平台仅仅关注arch下的一个目录如arm或者x86等

2),drivers:目录下的某一个driver,这个通常是做产品的里面的驱动都在这里

        drivers目录下的base,bus个别目录是内核驱动模型的框架代码

        drivers目录下的其他目录通常是按照驱动的分类,比如input,gpio等

3),init:内核最初启动的独立于芯片架构的common代码,入口是start_kernel

        至于是谁调用的start_kernel这个在arch下具体的架构,初学者可以先不关注,

        以这里作为内核的入口。

4),samples:子系统接口例子,不是内核代码,而是驱动接口的例子

5),Documentation:该目录下有很多参考文档

6),mm:内存管理相关的代码,初学者也可以不用细看,随着系统观的建立再看

7),lib:其他的目录用到的一些common的代码。也可以不用细看,用到的看

8),scripts:编译内核依赖的一些脚本有shell,python,perl等语言的各种辅助工具

        脚本,帮助编译输出内核,同时还有帮助调试内核的一些脚本。

对于初学者

certs/crypto/net/security/sound/tools/ubuntu/usr/virt
这几个目录可以直接忽略

二 如何阅读内核源码

linux内核这么多文件,有些子系统的核心代码,一个文件就上万行代码。初学者应该从哪里入手呢。首先这个前提是要有一个不错的c语言基础。

1,从一个具体的驱动入手,比如你手边的一个开发板,一个电脑等。首先能编译系统在平台运行起来,最初是找一个现成的照做。然后板子上硬件资源,都有驱动。可以找一个简单的驱动上手

2,不要从文件系统,网络子系统,usb,显示,sound等上手。先从最简单的比如触摸屏,键盘,鼠标,串口,gpio等上手。这样的驱动代码通常就几百行。但是这几百行代码中牵扯到的子系统却挺多的,比如input子系统,gpio子系统,中断注册,workqueue使用等。

3,通过这一个驱动你就知道了系统怎么注册一个最简单的module,然后用到的各个子系统的接口。但是你又不知道为什么。所以比如抓住input子系统看看input事件怎么处理,看看中断怎么注册管理,看看workqueue是什么原理。不一定一次性看懂,就像画画一样,刚开始是素描,还不清晰。不用着急,能看懂多少算多少

4,经过大概的阅读一个子系统,会有一点点的认识,这个时候可以从start_kernel开始看看驱动怎么注册的,module_init/fs_init等的优先级之类的,编译段的布局。然后看到怎么启动init进程。

5,熟悉简单的一些linux命令,在shell下应用看看你的应用怎么操作你的驱动比如/dev/xxx下的一个gpio,一个input节点等。

通过上面这些基本可以算是入门了,接下来就是不断的深入,带着为什么去寻找答案。

比如应用怎么操作到驱动,系统调用的原理。驱动中使用到的各个子系统的原理追踪。系统驱动模型是怎样的,怎么管理驱动。内存怎么管理,任务怎么管理。会发现似乎都是子系统。这就是共性。子系统之间又相互依赖。弱耦合。有一定的先后关系。

三 充分利用网络

在自己学习的同时不要网络充分利用网络资源,不懂的不知道的就直接百度,csdn等,同时也可以添加一些技术交流群。多向别人提问。

尽管有时候网络上或者别人的解释可能是错的。但是在不断的试错和理解纠偏中,就有了自己的理解。

内核代码这么多,不可能将每一句代码都理解的非常深入,这是不可能的。我们在不断的接触各种子系统。后面肯定会忘记。这完全没关系。更多是一种方法学的掌握更重要。不在于记住一个命令,记住一个api。而在于框架的共性。做的时候能熟练起来就好了。这里我想起来一句话,倚天屠龙记中张三丰对张无忌说的一段对话:

张三丰:无忌,看清楚没有

张无忌:看清楚了

张三丰:还记着没有

张无忌:已忘记了一大半

张三丰:现在呢

张无忌:我这下全忘了,忘的干干净净

张三丰:不坏不坏,忘得真快

读内核也是一样的,读的代码多了,写的多了,会发现共性。我们会发现无论是内核,无论是应用程序,他们的设计模式,框架有太多的相似处。区别在于业务的差异。而业务是做这件事的时候去了解的。这样都能快速上手。

最后

我们从小到大读了十几年的书,我们还记得多少呢,肯定不多。但是他对我们思维方式的影响却是潜移默化的。

文章标签: linux
推荐指数:

真诚点赞 诚不我欺~

linux源码目录结构

点赞 收藏 评论

关于作者

阿木木
阿木木

热衷于技术钻研与技术分享的小白白~~

等级 LV5

粉丝 3

获赞 15

经验 1388