首页 理论教育深入剖析Linux设备驱动设计

深入剖析Linux设备驱动设计

【摘要】:从图5-14可见,具体的设备模型的初始化流程在系统已经基本初始化完毕后执行,这时候sys文件系统作为一种特殊的文件系统已经注册并初始化,具体的设备初始化会在do_initcalls以函数表的形式进行,在这之前就是设备模型初始化的好时机,由driver_init来完成,其内部会进行总线管理初始化,功能设备管理初始化,platform总线初始化等。这样就对设备模型的设计框架有了基本的认识。

设备可以说是在内核管理中最具复杂性和多样性的部分,如图5-9所示。从图5-9可见,设备类型如此繁杂,需要管理各种不同并且差异极大的设备,在系统层面又要对它们进行统一管理,实现难度非常大。主要的难度体现在既要适应这些多样性还要提供统一的视角来进行管理。

设备管理要对各种不同设备进行生命周期管理、电源管理、设备发现以及驱动动态绑定和管理,这就要求有一个良好的模型对不同的设备在各个层面进行管理。这些是针对设备模型,在内核内部资源管理方面提出的需求。另外一个重要的需求是站在用户的角度,希望设备模型能够提供给用户一个框架,通过该框架用户可以方便地观察设备状态和设置设备属性。

1ᤫ物理设备管理的整体抽象模型

先来看看设备模型如何满足物理设备管理的需求,在介绍硬件的时候可以看到很多物理设备都是挂在物理总线上的,而处理器内部特别是SoC内部的设备虽然有片内总线,但是片内总线是硬件逻辑并没有软件抽象的管理实体,这样内部的设备就显得散乱,为了完成以上的管理需求,内核将整个系统的物理设备进行了一定的抽象组织,形成了抽象总线加物理总线的框架结构如图5-10所示。

978-7-111-49426-3-Chapter05-19.jpg

图5-9 Linux内核设备复杂多样性

978-7-111-49426-3-Chapter05-20.jpg

图5-10 设备模型的抽象组织

从图5-10可见,设备模型通过抽象的platform bus将与处理器联系紧密(片内设备)但逻辑并不相关的物理设备组织在一起,这样从整体上整个物理系统就形成了总线加设备的组织结构。另外由于设备是需要相应地操作才能工作,需要将这些操作抽象成为设备驱动。对整个物理设备系统进行总结,只需要总线、设备驱动和设备三个管理实体就可以完成管理物理设备的需求,这些总线上的物理设备相应的生命周期、驱动绑定以及管理就可以通过总线来完成。

在介绍设备分类的时候,将设备分为功能型设备和总线型设备,这里看到的模型是通过总线管理各种物理设备,但是此模型并没有完全站在用户使用的视角考虑,用户的视角更关心的是设备的功能,所以同样需要进行功能型设备的管理,虽然在物理上它们是一个设备,但是逻辑上应该分开管理(逻辑功能设备会和物理设备关联),于是将功能型设备的管理放入功能框架中进行就显得比较合理,只是要与设备模型框架进行交互。

2ᤫ观察、设置和管理设备的解决方案

对用户从各种角度方便地观察和设置设备的需求,最好采用Linux统一的方式———文件系统,内核针对性的设计了sys文件系统框架来满足这些需求。整个sys系统框架如图5-11所示。

978-7-111-49426-3-Chapter05-21.jpg

图5-11 sys文件系统组织

从图5-11可见,sys文件系统提供了总线(bus)管理的视角和功能分类(class)管理的视角,另外还提供了整体的电源管理以及系统参数的设置。

内核中数据结构与sys文件系统关系如图5-12所示。

从图5-12可见,实际的设备和驱动是通过kobject来进行管理的,而上层的kset和sub-system更多是用来组织相关的底层设备模型中的设备和驱动,而最下层的attribute(属性)是与设备和驱动等相关的实体表示为sys文件系统的文件。

978-7-111-49426-3-Chapter05-22.jpg

图5-12 sys文件系统与数据结构关系

先来看看重要的数据结构kobject,其内容如下:

978-7-111-49426-3-Chapter05-23.jpg

kobject承担了两部分的管理功能。其一是通过kref承担了生命周期管理(通过引用计数实现)功能,kobject是高度的抽象实体,对具体的实体(注意这些实体可以不是设备或者驱动,而是一些模块属性)生命周期的状态和管理则通过内嵌kobject来完成,这样需要抽象的kobject到具体实体的转换,这种转换通过ktype来实现,转换通常是在具体的实体释放以及sys文件系统的操作中需要。(www.chuimin.cn)

针对这些功能,内核提供了一系列接口进行相关操作,首先是引用计数的接口,具体如下:

978-7-111-49426-3-Chapter05-24.jpg

这些接口主要是针对引用计数的增减进行操作,release中可以进行抽象到具体的转换,相应的允许内核除kobject之外包含kref的实体,进行生命周期的管理。

对设备模型中的kobject内核提供如下的接口进行生命周期的管理:

978-7-111-49426-3-Chapter05-25.jpg

下面以kobject_put为例看一下是如何实现的:

978-7-111-49426-3-Chapter05-26.jpg

可见其就是使用kref的接口进行,其中有相对于kref具体的转换接口kobject_release。kobject_release中会调用kobject_cleanup,下面来看看kobject_cleanup的具体实现:

978-7-111-49426-3-Chapter05-27.jpg

978-7-111-49426-3-Chapter05-28.jpg

这样就实现了生命周期的管理功能。

kobject的另一个功能就是完成sys文件系统的组织功能,通过parent、kset、sd等链接完成该功能。相应的组织关系如图5-13所示。

关于设备模型的初始化,相关工作并不需要太早执行只要在具体的设备初始化之前执行即可,图5-14展示了内核设备模型在整个系统的初始化的位置及流程,这对理解设备模型有着实际的意义。

从图5-14可见,具体的设备模型的初始化流程在系统已经基本初始化完毕后执行,这时候sys文件系统作为一种特殊的文件系统已经注册并初始化,具体的设备初始化会在do_initcalls以函数表的形式进行,在这之前就是设备模型初始化的好时机,由driver_init来完成,其内部会进行总线管理初始化,功能设备管理初始化,platform总线初始化等。其中会向sys文件系统中添加对应的节点。sys文件系统中设备相关的初始化则在devices_init中执行,细节如图5-15所示。

978-7-111-49426-3-Chapter05-29.jpg

图5-13 sys文件系统数据结构组织关系

978-7-111-49426-3-Chapter05-30.jpg

图5-14 设备模型初始化

978-7-111-49426-3-Chapter05-31.jpg

图5-15 sys文件系统设备相关初始化

从图5-15可见,主要的几个与device相关的目录在此创建,为后续实体在相应目录下创建做准备。这样就对设备模型的设计框架有了基本的认识。