之前是学习字符设备驱动,但是在期间涉及到了一些设备模型中的东西,如自动创建设备节点,在这之后将深入学习这部分,从而也能更加清楚设备节点是如何创建的。这部分的东西较多,先整体理清框架,然后逐个去理解,最后整合一下,就清晰懂得这些模糊的概念所表述的用意。
Linux设备模型的目的:为内核建立一个统一的设备模型,从而又一个对系统结构的一般性抽象描述。
换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要新添加设备或驱动提供一般性的统一接口。
Linux设备模型的核心是使用Bus、Class、Device、Driver四个核心数据结构,将大量的、不同功能的硬件设备(以及驱动该硬件设备的方法),以树状结构的形式,进行归纳、抽象,从而方便Kernel的统一管理。
Linux设备模型的作用:
1.设备驱动模型实现uevent机制,调用应用层的medv来自动创建设备文件
2.设备驱动模型通过sysfs文件系统向用户层提供设备驱动视图,
3.设备驱动模型提供统一的电源管理机制
4.备驱动模型提供各种对象实例的引用计数,防止对象被应用层误删
5.设备驱动模型提供多种方式给应用层,用户和内核可以通过sysfs进行交互,如通过修改/sys目录下设备的文件内容,即可以直接修改设备对应的参数
设备模型,就是一套抽象出来用于管理设备的东西,它在内核空间已数据结构相互关联,在用户空间以文件目录的从属关系展示,方便了内核的统一化管理,也方便了用户的分类和使用,
先从每个结构体介绍,然后从一个驱动实例来剖析底层模型是如何组建的。
Linux设备模型学习分为:
Linux设备底层模型,描述设备的底层层次实现(kobject)(kset)(ktype)
Linux上层容器,包括总线类型(bus_type
)、设备(device
)和驱动(device_driver
)
device、driver、bus、class是组成设备模型的基本数据结构。kobject是构成这些基本结构的核心,kset又是相同类型结构kobject的集合
kobject和kset共同组成了sysfs的底层数据体系
Bus(总线):Linux认为(可以参考include/linux/device.h中struct bus_type的注释),总线是CPU和一个或多个设备之间信息交互的通道。而为了方便设备模型的抽象,所有的设备都应连接到总线上(无论是CPU内部总线、还是虚拟的总线“platform Bus”)。
Device(设备):抽象系统中所有的硬件设备,描述它的名字、属性、从属的Bus、从属的Class等信息。
Device Driver(驱动):Linux设备模型用Driver抽象硬件设备的驱动程序,它包含设备初始化、电源管理相关的接口实现。而Linux内核中的驱动开发,基本都围绕该抽象进行(实现所规定的接口函数)。
Class(类):在Linux设备模型中,Class的概念非常类似面向对象程序设计中的Class(类),它主要是集合具有相似功能或属性的设备,这样就可以抽象出一套可以在多个设备之间共用的数据结构和接口函数。因而从属于相同Class的设备的驱动程序,就不再需要重复定义这些公共资源,直接从Class中继承即可。
在这套抽象的设计思想中,主要的还是体现了面向对象,这也是C语言过程的语言用以面向对象编程的典范之作。
从这几个点的深入学习就会理解Linux设备模型的搭建,后边再加入字符设备驱动,这样就能完整的理解这个设备模型的作用,以及在驱动开发上的优势
Linux设备模型的核心思想:
- 用Device(struct device)和Device Driver(struct device_driver)两个数据结构,分别从“有什么用”和“怎么用”两个角度描述硬件设备。这样就统一了编写设备驱动的格式,使驱动开发从论述题变为填空体,从而简化了设备驱动的开发。
- 同样使用Device和Device Driver两个数据结构,实现硬件设备的即插即用(热拔插)。
在Linux内核中,只要任何Device和Device Driver具有相同的名字,内核就会执行Device Driver结构中的初始化函数(probe),该函数会初始化设备,使其为可用状态。
而对大多数热拔插设备而言,它们的Device Driver一直存在内核中。当设备没有插入时,其Device结构不存在,因而其Driver也就不执行初始化操作。当设备插入时,内核会创建一个Device结构(名称和Driver相同),此时就会触发Driver的执行。这就是即插即用的概念。 - 通过”Bus–>Device”类型的树状结构解决设备之间的依赖,而这种依赖在开关机、电源管理等过程中尤为重要。
试想,一个设备挂载在一条总线上,要启动这个设备,必须先启动它所挂载的总线。很显然,如果系统中设备非常多、依赖关系非常复杂的时候,无论是内核还是驱动的开发人员,都无力维护这种关系。
而设备模型中的这种树状结构,可以自动处理这种依赖关系。启动某一个设备前,内核会检查该设备是否依赖其它设备或者总线,如果依赖,则检查所依赖的对象是否已经启动,如果没有,则会先启动它们,直到启动该设备的条件具备为止。而驱动开发人员需要做的,就是在编写设备驱动时,告知内核该设备的依赖关系即可。 - 使用Class结构,在设备模型中引入面向对象的概念,这样可以最大限度地抽象共性,减少驱动开发过程中的重复劳动,降低工作量。