,总结浅谈Linux驱动到设备模型再到设备树

1.最初Linux驱动架构

  Linux驱动会在初始化函数中向内核注册file_operations结构体,结构体里面就包含一些基本的open,close函数。Linux驱动中也会去实现这些函数。并且相对应的硬件信息也在这个驱动中。以LED为例,驱动程序中会将LED的引脚地址映射成虚拟地址,然后在open函数里面进行写操作。

  当APP调用open函数的时候,就会通过一系列转换,最后调用到驱动中的open函数。(这边就不具体描述APP怎么调用到驱动中的open函数)。

弊端:  

  可以发现这种驱动,设备和驱动没有分离。也就是说,设备的信息是硬编码在驱动代码中的,会给驱动程序造成极大的限制。如果硬件有改动,那么必然要修改驱动代码,驱动的通用性将会非常的差。

2.总线、设备和驱动

  以USB总线为例:当接入一个USB设备时,USB总线会立即感知到这件事,并去遍历所有注册在USB总线上的驱动,然后调用驱动中的一段代码来测探是否能够驱动刚插入的USB设备,如果可以,那么总线完成驱动和设备之间的绑定。

  Linux设备模型为这三种对象各自定义了对应的类:

  •   struct bus_type代表总线
  •   srtuct device代表设备
  •   struct device_driver代表驱动

  这样就将设备的硬件信息和驱动分离开来。设备专门用来描述硬件相关的信息,而驱动和设备绑定成功后,驱动负责从设备中动态获取这些资源信息,当设备的资源改变后,只是设备改变而已,驱动的代码可以不做任何修改,这就大大提高了驱动代码的通用性。

  通常情况下,总线已经在内核中实现好,我们只需要写对应总线的驱动,有时候还会编写相应的设备注册代码。

3.平台设备及其驱动

  platform总线:有的设备并没有对应的物理总线,比如LED、RTC和蜂鸣器等。为此,内核专门开发一种虚拟总线——platform总线,用来连接这些没有物理总线的设备或者一些不支持热插拔的设备。

  平台设备是用struct platform_device结构来表示的。

4.Linux设备树

  在Linux内核源码的ARM体系结构引入设备树之前,相关的BSP代码中充斥了大量的平台设备(Platform Device)代码,而这些代码大多数都是重复的。之前的内核移植工作有很大一部分工作就是在复制一份BSP代码,并修改BSP代码中和目标板中与特定硬件相关的平台设备信息。

  设备树是一个描述硬件的数据结构。它只是提供了一种语言,将硬件配置从Linux内核源码中提取出来。