ITKeyword,专注技术干货聚合推荐

注册 | 登录

linux设备模型之总线 设备 和驱动

tianxiawuzhei 分享于 2012-04-28

推荐:Linux设备驱动模型之底层数据结构

本文简单介绍构成Linux设备驱动模型的最底层的数据结构:kobject、kset和kobj_type等等。kobject是组成设备模型的基本结构,在sysfs中显示的每一个对象,都对应

2020腾讯云“6.18”活动开始了!!!(巨大优惠重现!4核8G,5M带宽 1999元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1059

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

《Linux内核修炼之道》读书笔记 1、 设备模型的上层建筑由总线(bus) 、设备(device)、 驱动(device_driver)这3个数据结构构成,设备模型表示了它们之间的连接关系。 在设备模型中,所有的设备都通过总线连接。总线可以是物理存在的,也可以是虚拟的。比如内部的platform总线。 设备是连接到某条物理或虚拟总线上的对象。可能是真正的物理对象,也可能的是虚拟对象。 驱动是用来和设备通信的软件程序。驱动可以从设备获得数据,也可以把相应数据发给设备进行处理。 2、数据结构 (1)、总线 struct bus_type { const char *name;总线类型的名称 struct bus_attribute*bus_attrs; struct device_attribute*dev_attrs; struct driver_attribute*drv_attrs; int (*match)(struct device *dev, struct device_driver *drv);设备和驱动能否对应,就是有该总线的match方式决定。不同总线的match方式不一样。 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); int (*probe)(struct device *dev); int (*remove)(struct device *dev); void (*shutdown)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state); int (*suspend_late)(struct device *dev, pm_message_t state); int (*resume_early)(struct device *dev); int (*resume)(struct device *dev); struct pm_ext_ops *pm; struct bus_type_private *p; }; 现在如上数据结构和书中讲的有所不同,只不过有包装了一层数据结构struct bus_type_private *p,源码如下: /**

* struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure.

*

* @subsys - the struct kset that defines this bus.

This is the main kobject subsys描述该总线的子系统,它连接到全局量kset bus_subsys中。

* @drivers_kset - the list of drivers associated with this bus 该总线系统里所有驱动的集合

* @devices_kset - the list of devices associated with this bus 该总线系统里所有设备的集合

* @klist_devices - the klist to iterate over the @devices_kset 该总线里的设备用klist指针连成一个链表

* @klist_drivers - the klist to iterate over the @drivers_kset 驱动链表

* @bus_notifier - the bus notifier list for anything that cares about things

* on this bus.

* @bus - pointer back to the struct bus_type that this structure is associated

* with.

*

* This structure is the one that is the actual kobject allowing struct

* bus_type to be statically allocated safely.

Nothing outside of the driver

* core should ever touch these fields.

*/ struct bus_type_private { struct kset subsys; struct kset *drivers_kset; struct kset *devices_kset; struct klist klist_devices; struct klist klist_drivers; struct blocking_notifier_head bus_notifier; unsigned int drivers_autoprobe:1; struct bus_type *bus; }; 在sysfs文件系统中,我们可以清晰地看到它们之间的联系。kset bus_subsys对应于/sys/bus这个目录。每个bus_type对象都对应/sys/bus目录下的一个子目录,如PCI类型对应于/sys/bus/pci。 在每个这样的目录下都存在两个子目录:devices和drivers。 (2)、设备驱动device_driver struct device_driver { const char *name;驱动程序名称 struct bus_type*bus;该驱动所管理的设备挂接的总线类型 struct module*owner; const char *mod_name;/* used for built-in modules */ int (*probe) (struct device *dev);查询一个特定设备是否存在及驱动是否可以使用它的函数 int (*remove) (struct device *dev); void (*shutdown) (struct device *dev); int (*suspend) (struct device *dev, pm_message_t state); int (*resume) (struct device *dev); struct attribute_group **groups; struct pm_ops *pm;电源管理 struct driver_private *p; }; 与总线类似 struct driver_private { struct kobject kobj; struct klist klist_devices;该驱动程序能操作的设备链表 struct klist_node knode_bus; struct module_kobject *mkobj; struct device_driver *driver; }; 注:device_driver结构很少单独使用,而通常将其嵌入到一个驱动的高层中。如platform驱动 struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*suspend_late)(struct platform_device *, pm_message_t state); int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct pm_ext_ops *pm; struct device_driver driver; }; (3)、device设备 struct device { struct klistklist_children;设备列表中的孩子列表 struct klist_nodeknode_parent; /* node in sibling list */ struct klist_nodeknode_driver; struct klist_nodeknode_bus; 分别是挂入parent 、驱动、总线链表中的指针 struct device*parent; struct kobject kobj; charbus_id[BUS_ID_SIZE];/* position on parent bus */ const char*init_name; /* initial name of the device */ struct device_type*type; unsigneduevent_suppress:1; struct semaphoresem;/* semaphore to synchronize calls to

* its driver.

*/ struct bus_type*bus; /* type of bus device is on */设备所在总线 struct device_driver *driver;/* which driver has allocated this

device */该设备的驱动程序 void*driver_data;/* data private to the driver */ void*platform_data;/* Platform specific data, device

core doesn't touch it */ struct dev_pm_infopower; #ifdef CONFIG_NUMA intnuma_node;/* NUMA node this device is close to */ #endif u64*dma_mask;/* dma mask (if dma'able device) */ u64coherent_dma_mask;/* Like dma_mask, but for

alloc_coherent mappings as

not all hardware supports

64 bit addresses for consistent

allocations such descriptors. */ struct device_dma_parameters *dma_parms; struct list_headdma_pools;/* dma pools (if dma'ble) */ struct dma_coherent_mem*dma_mem; /* internal for coherent mem

override */ /* arch specific additions */ struct dev_archdataarchdata; spinlock_tdevres_lock; struct list_headdevres_head; struct klist_nodeknode_class; struct class*class; dev_tdevt;/* dev_t, creates the sysfs "dev" */ struct attribute_group**groups;/* optional groups */ void(*release)(struct device *dev); }; 注:device也通常嵌入到一个更大的结构体中。如platform设备 struct platform_device { const char* name; intid; struct devicedev; u32num_resources; struct resource* resource; }; 最后比较总线、设备和驱动的结构,我们发现,struct bus_type中有struct kset drivers和struct kset devices,同时struct device中有两个成员struct bus_type*bus和struct device_driver *driver,struct device_driver中有两个成员struct bus_type*bus和struct klist klist klist_devices. 4、 (1)、struct device中的bus表示这个设备练到那个总线上,driver表示这个设备的驱动是什么,struct device_driver中的bus表示这个驱动属于哪个总线,klist_devices表示这个驱动都支持哪些设备,因为这里device是复数,又是list,更因为一个驱动可以支持多个设备,而一个设备只能绑定一个驱动。当然,struct bus_type中的drivers和devices分别表示了这个总线拥有那些设备和驱动。 (2)、总线中两个链表的形成,内核每出现一个设备都要向总线汇报,或者说注册,每出现一个驱动,也要向总线注册。 (3)、现在,device可以在任何时刻出现,而driver也可以在任何时刻被加载,所以,出现的情况就是,每当一个struct device诞生,就会去bus的derivers链表中寻找它的另一半,反之,每当一个struct device_driver诞生,它就会去bus的devices链表中寻找它的那些设备。如果找到合适的,调用device_bind_driver绑定好。如果找不到,等待。

推荐:Linux 设备总线驱动模型

    尽管LDD3中说对多数程序员掌握设备驱动模型不是必要的,但对于嵌入式Linux的底层程序员而言,对设备驱动模型的学习非常重要。     Linux设备模型的目的:为

《Linux内核修炼之道》读书笔记 1、 设备模型的上层建筑由总线(bus) 、设备(device)、 驱动(device_driver)这3个数据结构构成,设备模型表示了它们之间的连接关系。 在设备模型中,所有的设备都

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。