系列文章目录
前言
一、内核模块 驱动以怎样的方式进入内核工作?
二、最简单的字符设备驱动 Linux 字符驱动长啥样?
三、文件系统与Linux 驱动 Linux 应用程序如何访问某个具体的设备驱动?
四、驱动的分层,分离思想 【总线,设备,驱动】为何提出分层,分离思想? 解决办法是啥?
五、Linux 内核代码简洁度的优化 (设备树) 为何引入设备树?
设备树 语法,编译,二进制文件结构
设备树如何被传递给Linux内核
内核如何展开设备树
驱动如何获取设备树中的信息
六、platform 设备驱动 将字符设备驱动转到总线,设备,驱动模型下
前言
Linux 驱动开发学习,主要是学习各种Linux 驱动框架,典型的如字符设备驱动框架,I2C驱动框架,SPI驱动框架,GPIO驱动框架等。这里涉及的各种概念比较多,如内核模块,设备树,总线,设备与驱动等等。好多的概念在各种驱动框架中都能发现。本人在学习Linux 驱动开发过程中,发现好多书籍在讲解Linux 驱动开发的某个概念时,经常是把局部信息讲的很细,但是并没有从更高层次或者说是从架构级别来讲解这个概念。比如,在ARM 平台方向的linux 驱动开发,设备树是无法避开的一个概念,许多Linux 驱动开发书籍在介绍设备树时,仅仅是详细的介绍了设备的语法。作为初学者,在读完设备树的语法后,语法很简单,而且好多设备树的实例也确实简单,但是真正到驱动代码里,总是感觉浑浑噩噩,不知道设备树的信息怎么就能配置驱动中的某个信息。
如下例(摘自树莓派的i2c 驱动):
图1 I2C 设备树配置
图2 I2C 适配器驱动中对时钟的配置
像上面两个图,图一中设备数描述的clock 仅仅简单一行。图二中关于clock 的信息却又好多行。那么,驱动中的时钟信息是怎么跟设备树中的信息对应起来的呢?其实,这里有个前提,要了解Linux 的时钟管理框架 CCF。了解了CCF ,再结合I2C 的设备树信息,结合 I2C 适配器驱动代码就能理解了,而初学者往往是不知道这一点的。
所以,这里有个隐蔽点是初学者不知道的,就是设备树是简单的,但是其背后的驱动框架是复杂的。初学者在学习设备树时,注意力大多放到了语法和个别例子上,而对设备树实际涉及的驱动框架并不了解,所以容易造成感觉反反复复学了,但是总是感觉不是那么明白,不清晰的感觉。类似的问题还有,一会儿设备树,一会儿字符设备驱动,一会儿总线,设备,驱动框架等等。本文将阐述各个概念模块的原因,相互关系,从总体上讲述各个概念(或称模块)的关系问题,然后再从细节讲起。希望能以全局到局部的模式讲清楚 Linux 驱动的各种概念和驱动框架。
注意:
本文注重嵌入式Linux 驱动开发所涉及的各个子概念(知识点)的介绍及引入。以最佳学习路径的方式依次介绍,比较适合初学者。本文内容为本人个人在学习和开发过程中的总结与理解,如有错误欢迎讨论,指正。