linux 内核之旅

我不认为我是 linux 之上的高手,因为我的shell 没有达到c语言的 拿来即用的水平,而且我的内核开发主要集中于设备驱动的开发。但我确信我现在已经是一个入门者,可以再遇到问题的时候,迅速定位,然后给出正确的指导和答案。

 

linux内核难吗?

接触之初,和现在完全是两种答案。在学习linux之前,我做过几年的单片机开发,基本的51系列,msp430系列等等。这为我理解linux的对硬件的操作打下深刻基础。因为对于cpu而言,最基本的部分是相同的,比如时钟设置,看门狗,中断,GPIO,串口等等。这些在单片机开发的时候,是完全要自己编写驱动,使其适应不同要求的。所以,在转移到linux之上时,我的学习的线索,就是以linux系统对硬件操作为主线的。比如,我要知道linux是怎么操作cpu的时钟的,我就要知道linux的api是通过什么过程连接到最终的寄存器之上。

不断的探索,记录,理解,最终才对linux内核有了最初的了解。

在学习中,感觉与单片机开发,最大不同在于,linux有了接口的概念。在以前的开发过程中,从来没有把cpu的驱动控制器跟外围设备的驱动分开来操作,而在linux中有了bus的概念。bus的一端连着控制器,一端连着外围驱动。bus的接口屏蔽了不同cpu之上设备驱动器的不同,为外围驱动开发提供了统一的接口。

在学习之初,我梦想着,自己可以写一个bus驱动,但当我仔细查看内核源码时,发现linux内核几乎涵盖了所有的总线接口。而对应的cpu总线控制器的驱动,多数都由CPU开发者来提供。对于一个初级的驱动开发者来说,可以熟练的使用总线接口,开发外围设备驱动就可以满足要求了,不必理会bus另一端的具体实现。

但,我是学过硬件的,芯片采购,电路设计,pcb绘制都做过,所以我觉得自己应该了解的更深入一些。在设备驱动开发之中,最重要的就是理解device,bus,driver的概念。如果理解了三者之间的关系,那么设备驱动就明白一半了。设备驱动的其他部分就是内核中的基本概念,比如阻塞,同步,task,中断,还有用户层接口。

我想学习内核,除了从硬件上入手之外,还可以从用户层接口入手。毕竟不是很多人都有硬件的基础,所以如果对linux应用软件熟悉的话,那么最好的方法就是从用户层接口入手了。比如设备节点,proc 文件,sys文件,netlink,uevent,系统调用等等。当能够熟练的运用不同的接口,来操作硬件设备的时候,就是linux内核入门的时候。

既然已经入门了,这个时候,对当前所有的总线驱动都可以达到拿来即用的地步。下一步的目标是什么呢?内存管理,dma管理,中断管理,文件系统管理,启动过程。这一部分是走向linux精髓的必由之路。内存管理帮助我们了解不同内存分配api的优点和缺点,不同内存分配算法的特点,还有linux中的实存和虚存的空间分布等等。dma管理,可以使我们了解dma的启动过程,使用方法,这个部分也依赖于硬件。中断管理,帮助我们了解中断的组织和调用路由,以及中断的使用方法和注意要素。文件系统管理,可以让我们深入理解linux的vfs层,所有的操作能看到的就是vfs的接口。启动过程,我们可以知道 bootloader启动linux内核的参数和引导,硬件的初始化顺序,驱动的加载顺序,rootfs的挂载等等。

到了这一步,我想对于linux内核的学习,可以达到60%左右了吧。最后一部分就是linux的内核调度和网络协议栈。这两个部分是最重要的部分。任务调度是任何一个操作系统的核心,通过任务调度可以得出一个系统的优势和特点。关于内核调度,我想首先需要明白一个进程是如何创建并运行的。这个时候,就涉及到了linux系统的可执行程序的格式,比如elf。为什么一个程序,在shell中调用就可以执行了呢?先看看busybox中shell的代码,看看系统调用的代码,看看内核创建进程的过程等等。多个创建的进程在内核中是如何调度的呢?我只在大学的时候被告知了linux的几种调度算法,但亲自看看代码和实现过程将是另外的一种进步。如果你还看过其他系统的代码,比如VxWorks,可以比较一下两个系统的调度上的差异,以及这种差异导致的应用领域的不同(当然不全是调度差异导致的)。

网络协议栈是复杂的工程。也是我的欠缺之处。没有过多的涉及,我想知道socket是如何创建的,如何阻塞的,如果通信的,栈中的算法等等。或许网络协议栈不是工作中必须的,但是linux高手必须的。

跟很多前辈一样,同样觉得内核中的 Makefile和Kconfig比较重要,它们是挖掘内核的线索。另外,我觉得学习内核,应该从自己的兴趣点开始,比如你最想知道什么问题,然后去追查。那么,当你明白这一过程之后,你的知识库中就形成了一条线,可能这个过程之中,涉及了很多其他的不懂得知识,那么就让他停留在你的想象中,你觉得他是什么样子的,那么他就是什么样子的。关键的是,要抓住主线,抓住从上之下的传递过程。 这样在你的知识库中的线多到一定的数量时,你就拥有了一张网。几个线上的连接点或许就是你最初不了解的东西。如果在你将两条线编织在一起的时候,从更高的角度重新审视和总结一下过去的工作,将会有更多的理解。当你的网越织越大,最后填满内核各个方面的时候,就到达了新的里程碑。此后,你可以在线上挂自己的铃铛,或者你可以优化某些算法,使线跟线之间的链接更有序高效。

我不推荐把线上的每个铃铛都了如指掌,那需要太多时间。我们要掌握的是那一张网。如果要在网上添一个铃铛,你可以迅速定位到想要的位置就可以。甚至,我不知道该放在哪个位置,但我可以通过网上某个线索迅速的定位到那个位置,然后再学习连接方法都行。

linux内核就是一张网,其中的层次结构和接口,是引人入胜的地方。

如果网络上没有你要的答案,那么源码就是最佳解决方法。

一起加油吧!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值