以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
一、linux设备驱动模型简介
1、设备驱动模型的含义
设备驱动模型主要体现为以下四个方面:
(1)类class、总线bus、设备device、驱动driver
这四个概念分别对应着四个结构体。
见博客:Linux设备驱动模型2——总线式设备驱动组织方式_天糊土的博客-CSDN博客
(2)kobject结构体和对象生命周期
kobject结构体是高度抽象的结构体,表示内核的一个总的父类。
(3)sys文件系统
相关描述见博客:sys文件系统_天糊土的博客-CSDN博客_sys文件系统
(4)udev的介绍
相关描述见百科:udev_百度百科
相关描述见博客:linux下udev详解_wang@xing的博客-CSDN博客_linux udev
2、设备驱动模型的意义
设备驱动模型,负责实现与维护一些特性,比如电源管理、热插拔、对象生命周期、用户空间和驱动空间的交互等基础设施。
早期内核(2.4之前)没有统一的设备驱动模型,但因为那时候设备较少,照样可以用。
在设备越来越多、功耗要求等新特性的情况下,2.6版本中引入了设备驱动模型。设备驱动模型的目的,是为了简化驱动程序编写,但是客观上设备驱动模型本身设计和实现很复杂。
3、驱动开发的2个点
驱动开发涉及两个方面:
(1)驱动源码本身编写与调试,重点在于对硬件的了解。
(2)驱动什么时候被安装,驱动中的函数什么时候被调用,怎样被调用(比如probe()函数还是直接调用)?之前通过写应用程序来安装,现在希望自动安装、卸载(热插拔),这些跟硬件无关,完全和设备驱动模型有关。
二、设备驱动模型的底层架构
设备驱动模型的底层架构,主要体现在以下三个结构体。
它们是/sys/下所有内容的实现机制,包括目录的组织,操作方法,数据结构等。
1、struct kobject
struct kobject {const char *name;struct list_head entry;struct kobject *parent;struct kset *kset;struct kobj_type *ktype;//每个kobject都绑定一个ktypestruct sysfs_dirent *sd;struct kref kref;unsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1; };
(1)此结构体定义在linux/kobject.h中,是最基本的结构体,被其他结构体作为元素。
(2)该结构体提供一些公用型服务:
- 对象引用计数(引用计数为0时,可以释放,生命周期结束)。
- 维护对象链表(因此可以遍历)。
- 对象上锁(占用对象资源,不被其他占用)。
- 对用户空间的表示。
(3)设备驱动模型中的各种对象其内部都会包含一个kobject。
- 因此各对象可以使用kobject所提供的功能。
- 地位相当于面向对象体系架构中的总基类。
2、struct kobj_type
(1)每一个kobject都需要绑定一个ktype来提供相应的功能。
struct kobj_type {void (*release)(struct kobject *kobj);const struct sysfs_ops *sysfs_ops;struct attribute **default_attrs;const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);const void *(*namespace)(struct kobject *kobj); };
(2)sysfs_ops,提供该对象在sysfs中的操作方法(show和store)。
struct sysfs_ops {ssize_t (*show)(struct kobject *, struct attribute *,char *);ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); };
(3)attribute,提供在sysfs中以文件形式存在的属性,其实就是应用接口。
struct attribute {const char *name;struct module *owner;mode_t mode; #ifdef CONFIG_DEBUG_LOCK_ALLOCstruct lock_class_key *key;struct lock_class_key skey; #endif };
(4)release函数,查看引用计数,去释放对象所占用的内存。
(5)总结:提供属性文件,提供“/sys/……”的操作方法。
3、struct kset
struct kset {struct list_head list;spinlock_t list_lock;struct kobject kobj;const struct kset_uevent_ops *uevent_ops; };
(1)kset的主要作用是做顶层kobject的容器类。
(2)kset的主要目的是将各个kobject(代表着各个对象)组织出目录层次架构。
(3)可以这样理解,kset就是为了在sysfs中弄出目录,从而让设备驱动模型中的多个对象能够有层次有逻辑性的组织在一起。