驱动模型对象

注,本文中用到的图片来《自存储技术原理分析》一书)

驱动模型对象

linux驱动模型适用于linux各种子系统,他描述了总线类型,驱动,设备之间以及类,接口之间的关系,每个子系统都有属于自己的唯一的总线类型,他上面链接了注册到这个总线类型上的多个设备,另外啊还将注册到这个总线类型的多个驱动链接到一起。

总线类型,驱动,设备这三者的关系使得子系统支持热插拔变得很容易,早期计算机不支持热插拔,驱动必须在设备被发现前被加载,而支持热插拔系统可以运行驱动已经加载的情况下安装设备。linux驱动模型处理方法:在设备被防线时候,他被加入到所注册总线类型的设备链表,然后在该总线类型的驱动链表中查找可以处理这个设备的驱动并绑定;类似,在驱动被加载时候,被加入到他所注册的总线类型的驱动链表,同时在改总线类型的设备链表中查找并绑定可以处理的设备,这样,设备发现与驱动加载顺序就不那么重要了。

每个设备还可以唯一属于某个类,设备被链入到类的设备链表中,类还有一个接口链表,用于链接注册到到该类的所有接口,在设备被发现或者接口被添加时候,无论何种顺序只要他们属于同一个类,那么接口注册的回调函数都会被作用在设备之上


 

 总线类型

linux驱动模型中的总线类型结构使用bus-typebus_type_private结构共同表示,下面是bus_type_private结构

 

每个总线类型被注册后,将在/sys/bus下面创建一个和他名字对应的子目录,该子目录下游有2个子目录分别是driversdevices,某些子系统都会定义自己的总线类型,初始化就是向内核注册总线类型。

bus_register():会在/sys/bus/下创建一个子目录,然后又会添加devices子目录,对应的kset保存在devices——kset中,以便将来在该总线类型下发现设备时候,向对应子目录中添加设备的符号链接。添加drivers子目录,kset保存在drivers_kset中,以便将来在该总线类型下加载驱动的时候,向对应的子目录添加驱动的子目录;初始化总线类型的设备链表和驱动链表。

bus_for_each_dev函数遍历总线类型的设备链表,bus_for_each_drv遍历总线类型的驱动链表,对于链表中每个设备或驱动,调用传入的回调函数fn,回调函数返回0就继续处理链表后一个设备或驱动,返回非零则退出循环,这主要用于设备和驱动的匹配

设备

使用devicedevice_driver共同表示,两个结构相互关联,各有一个域指向对方

device结构


 

device_private结构


 

每个设备被归到一种总线类型,通过bus域指向,设备也可以属于唯一的类,由class域指向,如果设备被绑定,则通过driver域指向对应的驱动,同内核对象一样,设备也被组织成层次结构,parent域指向父亲设别。这样,设备可以被加入到如下四种链表

所属总线类型的设备链表:总线类型的klist_devices为这个链表的表头,设备的knode_bus为链入此表的连接件

所属类的设备链表:类的class_device为这个表的表头,设备的knode_class为链入此表的连接件

绑定他的驱动的设备链表,驱动的klist_devices为表头,设备的knode_driver为链入此表的连接件

父设备的孩子链表,父设备的klist_children为表头,设备的knode_parent为链入此表的连接件

在实际中,驱动模型设备被嵌入到业务子系统的设备结构中,后者通过驱动模型设备被链接到业务子系统的总线类型实例,或者被连接到业务子类型的类实例,二者取一,也就是每个驱动模型设备只会使用knode_bus或者knode_class中的一个,如果需要同时链入到总线类型实例与类实例,则需要包含两个内嵌的驱动模型设备。

类似kobject,每个device都属于一种设备类型,结构为device_type定义了这种类型设备的公共方法和成员

device_type结构


 

设备被发现后,需要向linux驱动模型注册,设备注册的函数是device_register():此函数初始化设备,以及将设备添加到sysfs,分别调用device_initialize和的device_add函数。

device_initialize

将设备内嵌的kobject关联到内核对象集device_kset,然后调用devices_init(调用kset_create_and_add)他在sysfs文件系统中对应的目录为/sys/devices 此外,device_ksetuevent操作表赋值。同时设备device_ktype

device_add

负责将设备添加到系统,设备的私有据结构可能还没有分配,这时候会分配,同时调用setup_parent,确定设备在sysfs中的位置(实际是设置device结构中内嵌的kobjectparent域,决定设备在syfs文件系统的位置),调用kobjetc_add将设备的内嵌kobject添加到系统,这将在/sys/device中添加一个设备名为名的子目录。

如果设备有设备号,将在设备目录下创建dev属性对应的文件 ######,调用device_create_sys_dev_entry/sys/block 或者/sys/char下创建一个到设备所在目录(/sys/device/..)符号链接,链接名为###:###

调用device_add_class_symlinks如果设备属于某个类,则为设备创建和类相关的符号链接,调用bus_add_device,如果设备有指定的总线类型,则加入到该总线类型。这样。设备自身你的添加工作完成,最后调用kobject_uevent向用户空间报告KOBJ_ADD事件

然后调用bus_probe_device试图将设备绑定到某个驱动。

如果制定parent,则将设备添加到他的孩子链表,同样,如果设置了class,则将设备添加到类的设备链表

驱动

驱动的相关与设备类似,主要也是将驱动添加到总线类型的驱动链表呀,以及跟设备的一些关系。详细见源码 /driver/base/driver.c


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值