活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…
续接上篇继续看看Linux的设备驱动管理之内核对象中的bus,devices和driver的结构定义及说明。
devices的抽象结构为struct device,定义在kernel/include/linux/device.h
struct device {
/*父设备*/
struct device *parent;
/*该device的私有变量*/
struct device_private *p;
/*该设备对应的kobject*/
struct kobject kobj;
const char *init_name; /* initial name of the device */
const struct device_type *type;
struct mutex mutex; /* mutex to synchronize calls to
* its driver.
*/
/*该device所需要注册的总线*/
struct bus_type *bus; /* type of bus device is on */
/*该设备所绑定的驱动*/
struct device_driver *driver; /* which driver has allocated this
device */
/*platform模块相关的参数,device-bus-driver模型不关心该变量*/
void *platform_data; /* Platform specific data, device
core doesn't touch it */
/*电源管理相关的内容*/
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
/*引脚配置相关的内容,可实现对该设备关联的引脚进行初始化与设置操作*/
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
/*numa相关的内容,本次不涉及*/
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
/*以下为dma 相关的内容*/
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_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_head dma_pools; /* dma pools (if dma'ble) */
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
#ifdef CONFIG_CMA
struct cma *cma_area; /* contiguous memory area for dma
allocations */
#endif
/* arch specific additions */
struct dev_archdata archdata;
/*该变量主要用于设备树模块使用,该device_node表示dts中的节点信息,当开启OF宏时,driver会根据该device_node
中的节点名称以及driver中of相关的节点名称,进行device-driver的匹配检测操作,从而支持设备树*/
struct device_node *of_node; /* associated device tree node */
struct acpi_dev_node acpi_node; /* associated ACPI device node */
/*设备号,当为block/char设备时,需要设置该值,通过该值会实现该设备对应kobject与/sysfs/dev/char 、/sysfs/dev/block
对应的kobject的链接关联*/
dev_t devt; /* dev_t, creates the sysfs "dev" */
u32 id; /* device instance */
spinlock_t devres_lock;
struct list_head devres_head;
/*链接至系统class模块的kset的链表中*/
struct klist_node knode_class;
/*该设备所属的类*/
struct class *class;
/*该设备的默认属性组*/
const struct attribute_group **groups; /* optional groups */
/*release接口,当对该设备进行释放其kobject时,会通过dev_kobj_type的release接口进行device的释放(
该接口会调用device->release进行device的释放操作)。*/
void (*release)(struct device *dev);
struct iommu_group *iommu_group;
};
driver的抽象表现形式为struct device_driver,这里所讲的driver即是设备驱动,即device_driver,定义在kernel/include/linux/device.h
struct device_driver {
const char *name;/*驱动名称*/
struct bus_type *bus;/*该驱动所依附的总线*/
/*该驱动所属module*/
struct module *owner;
/*模块的名称*/
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
/*设备树使用的设备id*/
const struct of_device_id *of_match_table;
const struct acpi_device_id *acpi_match_table;
/*该驱动的探测接口*/
int (*probe) (struct device *dev);
/*该驱动的移除接口*/
int (*remove) (struct device *dev);
/*shutdown 、suspend、resume主要是对应电源管理方面的接口*/
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
/*该驱动所相关的属性接口,主要用于与sysfs模块管理*/
const struct attribute_group **groups;
/*性能管理相关的内容*/
const struct dev_pm_ops *pm;
/*该驱动模块相关的私有变量,主要包括驱动对应的kobject、所属模块的kobject等*/
struct driver_private *p;
};
kernel/drivers/base/base.h
struct driver_private {
/*该驱动对应的kobject*/
struct kobject kobj;
/*用于汇聚该驱动所绑定的所有设备*/
struct klist klist_devices;
/*用于链接至xxx_bus_type的klist_drivers链表上*/
struct klist_node knode_bus;
/*该驱动所属模块的kobject*/
struct module_kobject *mkobj;
/*指向本driver_private类型变量所属的driver变量*/
struct device_driver *driver;
};
bus是Linux上一个很重要的概念,它搭载着devices和drivers且管理着它们。bus的抽象表现为struct bus_type,定义在kernel/include/linux/device.h
struct bus_type {
/*总线名称*/
const char *name;
/*总线对应设备名称*/
const char *dev_name;
/*该总线对应的device*/
struct device *dev_root;
struct bus_attribute *bus_attrs;/*总线属性*/
struct device_attribute *dev_attrs;/*设备属性*/
struct driver_attribute *drv_attrs;/*驱动属性*/
/*match接口,用于进行device与driver的匹配*/
int (*match)(struct device *dev, struct device_driver *drv);
/*uevent接口,用于发送kobject event,供应用层mdev/udev使用*/
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
/*总线的probe接口,该接口会调用具体驱动的probe接口*/
int (*probe)(struct device *dev);
/*总线的remove接口,一般该接口主要是调用具体驱动的remove接口*/
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct dev_pm_ops *pm;/*pm相关*/
struct iommu_ops *iommu_ops;
/*该接口包含了该bus对应kobject、device对应的kset、driver对应的kset、
链接所有设备的链表、链接所有驱动的链表等*/
struct subsys_private *p;
struct lock_class_key lock_key;
};
关于bus,devices和driver描述完后,还有一个重要的概念叫做class.定义在kernel/include/linux/device.h
struct class {
const char *name;
struct module *owner;
/*该变量定义了该类别默认的属性*/
struct class_attribute *class_attrs;
/*该变量定义了所有属性该类别的设备所定义的默认的属性*/
struct device_attribute *dev_attrs;
struct bin_attribute *dev_bin_attrs;
struct kobject *dev_kobj;
/*事件接口(用于向应用层发送事件如class设备的添加与移除等)*/
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, umode_t *mode);
/*释放接口*/
void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
const struct dev_pm_ops *pm;
struct subsys_private *p;
}

