现在的位置: 首页 > 操作系统 > 正文

linux设备驱动模型

2017年05月19日 操作系统 ⁄ 共 2679字 ⁄ 字号 评论关闭

1 底层机制

Linux 的设备驱动模型的底层机制主要包括:kobject,kobj_type,kset 等几个结构。这几个

结构的定义在include/linux/kobject.h 中。

1.1 kobject 代表设备驱动模型中一个基本对象,类似于MFC 中最顶层的基类CObject。每个kobject 都对应于sysfs 中的一个目录。上层结构例如device,device_driver,bus_type 都嵌入了一个kobject,这相当于面向对象程序设计语言中的继承机制

1.2 kobj_type是kobject 所属的类型,定义了某种类型的kobejct 的公共的属性和操作

1.3 kset 是一个kobject 集合(或容器),包含了一系列的kobject。需要注意的是,kset 内部也嵌入了kobject,这表明kset 本身也是一个kobject

2 高层数据结构

高层主要包括三个结构:device,device_driver,bus_type 。这几个结构的定义在

include/linux/device.h 中。

2.1 device代表一个设备,对应于/sys/devices/下的一个目录

2.2 device_driver代表一个设备驱动程序,对应于/sys/bus/XXX/drivers/下的一个目录

2.3 bus_type代表一个总线,对应于/sys/bus/下的一个目录。

2.4 match()方法用于判断挂在总线下的某个device 和某个device_driver 是否匹配,在一个

device 或一个device_driver 注册到总线上时调用。uevnet()方法用于为uevent 机制添加环境变量,在处理uevent 时被调用。其它方法都是操作总线上挂接的device 的

2.5 probe(),remove(),shutdown(),suspend(),resume()这几个方法在device_driver 中也定

义了。内核在调用这些方法时,会优先调用bus_type 中定义的方法。如果相应的方法在

bus_type 中未定义,才会去调用device_driver 中定义的方法。

3 bus_type、device 和device_driver 之间的关系

3.1 bus_type 相当于一个容器,是device 和device_driver 的管理机构,它包含了一个device 集合(kset)和一个device_driver 集合(kset),分别表示挂在这个总线下的所有设备和所有设备驱动程序。

3.2 device_driver 挂在某个bus_type 下面,包含了一个device 集合(kset),表示这个驱动程序操作(或控制)的所有设备。device_driver 还包含一个bus_type 指针,表示驱动程序所在的总线。

3.3 device 挂在某个bus_type 下面,包含了一个device_driver 指针,表示这个设备对应的设备驱动程序。device 还包含一个bus_type 指针,表示设备所在的总线。需要说明的是,一个实际的总线在设备驱动模型中是用两个结构表示的:bus_type 和device。bus_type 代表总线类型,出现在/sys/bus/目录下;device 代表总线设备,出现在/sys/devices/

目录下,这表明实际的总线本质上是一种设备。

4在总线中添加和删除设备的过程:

(1) 设备添加

device_register(dev)->device_add(dev)-> kobject_uevent(KOBJ_ADD)

device_add(dev)->bus_attach_device(dev)->device_attach(dev)

->__device_attach(drv,dev)->bus_type():match(dev,drv)

then ->driver_probe_device()->really_probe()

->bus_type:probe()或device_driver:probe()

(2) 设备删除

device_unregister(dev)->device_del(dev)->bus_remove_device(dev)

->device_release_driver(dev)

->__ device_release_driver(dev)

->bus_type:remove()或device_driver:remove()

device_del(dev)->kobject_uevent(KOBJ_REMOVE)

(3) 当在总线上添加(或删除)设备时,会依次遍历总线上的所有驱动程序,调用总线定义的

match()方法检查要加入(或删除)的设备是否和驱动程序“匹配”,如果匹配成功,则对设备

调用总线或驱动程序中定义的probe(或remove)方法。添加设备时产生KOBJ_ADD uevent,

删除设备时产生KOBJ_REMOVE uevent

5 总结一下在总线中添加和删除驱动程序的过程:

(1) 驱动程序添加

driver_register(drv)-> bus_add_driver (drv)-> driver_attach(drv)

->__driver_attach(dev,drv)

->bus_type():match(dev,drv) then

->driver_probe_device()->really_probe()

->bus_type:probe() 或device_driver:probe()

driver_register(drv)-> kobject_uevent(KOBJ_ADD)

(2) 驱动程序删除

driver_unregister(dev)->bus_remove_driver(drv)-> driver_detach(drv)

->__ device_release_driver(dev) [dev-drv 管理的所有设备]

->bus_type:remove() 或device_driver:remove()

(3) 当在总线上添加(或删除)驱动程序时,会依次遍历总线上的所有设备,调用总线定义的

match()方法检查要加入(或删除)的驱动程序是否和设备“匹配”,如果匹配成功,则对设备

调用总线或驱动程序中定义的probe(或remove)方法。添加驱动程序时产生KOBJ_ADD

uevent,删除驱动程序时产生KOBJ_REMOVE uevent。[注:KOBJ_REMOVE uevent 在

kobject_put(&drv->p->kobj)中产生]

抱歉!评论已关闭.