Linux驱动开发学习归纳-2
来源:互联网 发布:西安儿童编程培训机构 编辑:程序博客网 时间:2024/06/18 14:26
【设备驱动模型】
设备驱动模型提供了硬件的抽象:使用该抽象完成很多硬件重复的工作,如电源管理、即插即用设备支持、与用户空间的通信等。
sysfs文件系统:Linux设备驱动模型由大量的数据结构和算法构成,非常复杂,因此引入sysfs文件系统来显示设备驱动模型的复杂关系。sysfs是一个只存在于内存中的文件系统。内核通过这个文件系统将设备信息导出到用户空间。sysfs文件系统是内核对象(kobject)、属性(kobj_type)及他们之间的相互关系的一种表现机制。用户可以从sysfs文件系统中读出内核数据,也可以将用户空间的数据写入内核中,从而设置驱动程序的属性和状态。
Linux 内核结构 和 sysfs文件系统 的对应关系:
Linux内核中的结构 sysfs中的结构
kobject <-----------------------------------> 目录
kobj_type <----------------------------------> 属性文件
对象之间的关系<--------------------------> 符号链接
在sysfs文件系统中,设备使用树形目录来表示,树形目录中的每个目录都对应于内核中的一个kobject对象。
59 struct kobject { 60 const char *name; 61 struct list_head entry; 62 struct kobject *parent; 63 struct kset *kset; 64 struct kobj_type *ktype; 65 struct sysfs_dirent *sd; 66 struct kref kref; 67 unsigned int state_initialized:1; 68 unsigned int state_in_sysfs:1; 69 unsigned int state_add_uevent_sent:1; 70 unsigned int state_remove_uevent_sent:1; 71 unsigned int uevent_suppress:1; 72 };每个kobject对象都有一些属性,这些属性有kobj_type结构体表示。
107 struct kobj_type {108 void (*release)(struct kobject *kobj);109 struct sysfs_ops *sysfs_ops;110 struct attribute **default_attrs;111 };
kobject和kobj_type之间的关系如图所示:
kobject始终代表sysfs文件系统中的一个目录,kobject对象的成员name是sysfs文件系统中的目录名。
kobject在sysfs文件系统中的位置由parent指针指定。
kobj_type是kobject的属性。attribute结构体表示一个属性。sysfs_ops表示对属性的操作函数。
28 struct attribute { 29 const char *name; 30 struct module *owner; 31 mode_t mode; 32 };
77 struct sysfs_ops { 78 ssize_t (*show)(struct kobject *, struct attribute *,char *); 79 ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); 80 };在编写设备驱动时,一般把kobject包含在一个更大的自定义结构体中。
另外,kobject可以通过kset组织成层次化的结构,kset是具有相同类型的kobject的集合,这也说明kset本身也对应一个目录。
154 struct kset {155 struct list_head list;156 spinlock_t list_lock;157 struct kobject kobj;158 struct kset_uevent_ops *uevent_ops;159 };kset与kobject的关系如图所示:
/////////////////////********************************************************************************///////////////////////////
设备驱动模型由三大组件构成:总线、设备、驱动。
其中总线是一个抽象的总线,所有的设备和驱动都会挂接到一个总线上。然后设备需要和对应的驱动程序绑定后才能使用。
1. 总线用bus_type表示:
51 struct bus_type { 52 const char *name; 53 struct bus_attribute *bus_attrs; 54 struct device_attribute *dev_attrs; 55 struct driver_attribute *drv_attrs; 56 57 int (*match)(struct device *dev, struct device_driver *drv); 58 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 59 int (*probe)(struct device *dev); 60 int (*remove)(struct device *dev); 61 void (*shutdown)(struct device *dev); 62 63 int (*suspend)(struct device *dev, pm_message_t state); 64 int (*resume)(struct device *dev); 65 66 const struct dev_pm_ops *pm; 67 68 struct bus_type_private *p; 69 };其中总线属性bus_attrs、设备属性dev_attrs、驱动属性drv_attrs,与kobject对应的属性类似。
38 struct bus_attribute { 39 struct attribute attr; 40 ssize_t (*show)(struct bus_type *bus, char *buf); 41 ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); 42 };
在bus_type结构体中定义了许多方法。当一条总线上的新设备或者新驱动被添加时,会一次或多次调用match()函数。当用户空间产生热插拔事件前,可能需要内核传递一些参数给用户程序,这只能使用环境变量来传递参数,传递环境变量的函数由uevent()实现。
bus_type_private是总线私有数据结构,主要包括了3个成员:代表该bus的subsys、挂接到该bus上的驱动集合drivers_kset、挂接到该bus上的设备集合devices_kset。
19 struct bus_type_private { 20 struct kset subsys; 21 struct kset *drivers_kset; 22 struct kset *devices_kset; 23 struct klist klist_devices; 24 struct klist klist_drivers; 25 struct blocking_notifier_head bus_notifier; 26 unsigned int drivers_autoprobe:1; 27 struct bus_type *bus; 28 };如果为驱动程序定义了一条新的总线,则需要调用bus_register()函数进行注册,当从系统中删除一条总线时,则需要调用bus_unregister()函数进行删除。
2. 设备用device结构体表示:
379 struct device {380 struct device *parent;381 382 struct device_private *p;383 384 struct kobject kobj;385 const char *init_name; /* initial name of the device */386 struct device_type *type;387 388 struct semaphore sem; /* semaphore to synchronize calls to389 * its driver.390 */391 392 struct bus_type *bus; /* type of bus device is on */393 struct device_driver *driver; /* which driver has allocated this394 device */395 void *platform_data; /* Platform specific data, device396 core doesn't touch it */397 struct dev_pm_info power;398 399 #ifdef CONFIG_NUMA400 int numa_node; /* NUMA node this device is close to */401 #endif402 u64 *dma_mask; /* dma mask (if dma'able device) */403 u64 coherent_dma_mask;/* Like dma_mask, but for404 alloc_coherent mappings as405 not all hardware supports406 64 bit addresses for consistent407 allocations such descriptors. */408 409 struct device_dma_parameters *dma_parms;410 411 struct list_head dma_pools; /* dma pools (if dma'ble) */412 413 struct dma_coherent_mem *dma_mem; /* internal for coherent mem414 override */415 /* arch specific additions */416 struct dev_archdata archdata;417 418 dev_t devt; /* dev_t, creates the sysfs "dev" */419 420 spinlock_t devres_lock;421 struct list_head devres_head;422 423 struct klist_node knode_class;424 struct class *class;425 const struct attribute_group **groups; /* optional groups */426 427 void (*release)(struct device *dev);428 };同理有设备注册和注销,还有设备属性。
3. 驱动用device_driver结构体表示:
122 struct device_driver {123 const char *name;124 struct bus_type *bus;125 126 struct module *owner;127 const char *mod_name; /* used for built-in modules */128 129 bool suppress_bind_attrs; /* disables bind/unbind via sysfs */130 131 int (*probe) (struct device *dev);132 int (*remove) (struct device *dev);133 void (*shutdown) (struct device *dev);134 int (*suspend) (struct device *dev, pm_message_t state);135 int (*resume) (struct device *dev);136 const struct attribute_group **groups;137 138 const struct dev_pm_ops *pm;139 140 struct driver_private *p;141 };同理有驱动程序的注册和注销,还有驱动的属性。
- Linux驱动开发学习归纳-2
- Linux驱动开发学习归纳-1
- Linux驱动开发学习归纳-3
- Linux驱动开发学习归纳-4
- linux驱动开发学习
- linux驱动开发学习
- 【Linux开发】linux设备驱动归纳总结(五):4.写个简单的LED驱动
- 【Linux开发】linux设备驱动归纳总结(八):1.总线、设备和驱动
- 【Linux开发】linux设备驱动归纳总结(八):2.总线、设备和驱动的关系
- 【Linux开发】linux设备驱动归纳总结(九):1.platform总线的设备和驱动
- 【Linux开发】linux设备驱动归纳总结(十一):写个简单的看门狗驱动
- linux设备驱动归纳总结
- linux设备驱动归纳总结
- linux设备驱动归纳总结
- Linux-ASoC驱动归纳总结:
- linux设备驱动归纳总结
- linux设备驱动归纳总结
- Linux-ASoC驱动归纳总结
- 股票投资50本经典书籍
- AndroidAnnotations 是如何工作的
- OpenGL超级宝典笔记——纹理映射Mipmap
- 使用小米2有感
- 贴一个并查集的模板吧
- Linux驱动开发学习归纳-2
- 华为机试 题目2 - 字符串过滤
- CF - 407 - B. Long Path(dp)
- NYOJ-586 疯牛 二分枚举+贪心
- ubuntu 开发环境安装
- android 源码和兼容包
- 华为机试 题目3 - 字符串压缩
- oracle 通配符 转义
- 迭代式开发