Kobject相关
kobject描述结构体:
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;//指向父对象
struct kset *kset;
struct kobj_type *ktype;
struct 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;
};
初始化kobject结构体:
voidkobject_init(struct kobject *kobj, struct kobj_type *ktype);
将kobject对象注册到linux系统:
intkobject_add(struct kobject *kobj, struct kobject *parent,const char *fmt, ...);
初始化kobject并注册到linux系统:
int kobject_init_and_add(structkobject *kobj,struct kobj_type *ktype,
struct kobject *parent,const char *fmt, ...);
删除kobject对象:
voidkobject_del(struct kobject *kobj);
将kobject对象引用计数加1,并返回该对象指针:
struct kobject*kobject_get(struct kobject *kobj);
将kobject对象引用计数减1,减到0则调用release进行释放对象:
voidkobject_put(struct kobject *kobj);
kobject对象的一些属性:
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);
};
Kobject目录下的一个文件:(name为文件名)
structkobj_attribute {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj,struct kobj_attribute *attr,char *buf);
ssize_t (*store)(struct kobject *kobj,struct kobj_attribute *attr,
const char *buf, size_t count);
};
当用户读属性文件时调用show函数,属性存入buffer返回给用户:
ssize_t(*show)(struct kobject *,struct attribute *,char *);
当用户写属性文件时调用store函数,存储用户传入的属性:
ssize_t (*store)(structkobject *,struct attribute *,const char *,size_t);
相同类型kobject的集合kset,在sysfs中体现为一目录:
struct kset {
struct list_head list;
spinlock_t list_lock;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
};
内核中注册kset:
intkset_register(struct kset *kset);
内核中注销kset:
voidkset_unregister(struct kset *kset);
热插拔事件
在linux系统中,当系统配置发生变化时:如添加kset到系统;移动kobject,一个通知会从内核空间发送到用户空间,这就是热插拔事件。会导致用户空间中相应的处理程序(udev,mdev)被调用,会加载驱动程序,创建设备节点来响应热插拔事件。
操作集合kset_uevent_ops:kobject和kset状态发生变化时调用三个函数
structkset_uevent_ops {
//决定是否将事件传递到用户空间
int (* const filter)(struct kset *kset,struct kobject *kobj);
//用于将字符串传递给用户空间的热插拔处理程序
const char *(* const name)(struct kset *kset, struct kobject *kobj);
//将用户空间需要的参数添加到环境变量中
int (* const uevent)(struct kset *kset, struct kobject *kobj,
struct kobj_uevent_env *env);
};
总线
总线是处理器和设备之间的通道,在设备模型中,所有的设备都是通过总线相连,甚至是内部的虚拟“platform”总线。在linux设备模型中,总线由struct bus_type结构表示,定义在<linux/device.h>。
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, structdevice_driver *drv);
int (*uevent)(struct device *dev, structkobj_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 (*resume)(struct device *dev);
const struct dev_pm_ops *pm;
struct iommu_ops *iommu_ops;
struct subsys_private *p;
};
总线注册使用:
bus_register(structbusy_type *bus);新添加的总线会出现在/sys/bus下
总线删除使用:
bus_unregister(structbusy_type *bus);
匹配设备和驱动程序:
int (*match)(structdevice *dev,struct device_driver *drv);
当一个新设备或者驱动被添加到这个总线时,该方法被调用。用于判断指定的驱动程序是否能处理指定的设备。可以返回非零值。
总线方法:
int (*uevent)(structdevice *dev,char **envp,int num_envp,char *buffer,int buffer_size);在为用户空间产生热插拔事件之前,这个方法允许总线添加环境变量。
总线属性:
在structbus_attribute结构中描述总线属性。
structbus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *bus, char*buf);
ssize_t (*store)(struct bus_type *bus,const char *buf, size_t count);
};
BUS_ATTR(_name,_mode, _show, _store)。
创建总线属性文件:
intbus_create_file(struct bus_type * bus,structbus_attribute *attr);
删除总线属性文件:
voidbus_remove_file(struct bus_type * bus,structbus_attribute *attr);
设备
Linux中设备由struct device结构体描述
注册设备:
intdevice_register(struct device *dev);
删除设备:
void device_unregister(structdevice *dev);
设备属性:(由结构体struct device_attribute描述)
structdevice_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, structdevice_attribute *attr,char *buf);
ssize_t (*store)(struct device *dev, structdevice_attribute *attr,
const char *buf, size_t count);
};
DEVICE_ATTR(_name,_mode, _show, _store)。
创建设备属性文件:
int device_create_file(structdevice *device,const struct device_attribute *entry);
删除设备属性文件:
void device_remove_file(structdevice *dev,const struct device_attribute *attr);
驱动
总线中的驱动描述:
structdevice_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
const struct of_device_id *of_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_tstate);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
总线驱动注册:
intdriver_register(struct device_driver *drv);
总线驱动注销:
voiddriver_unregister(struct device_driver *drv);
驱动属性:
structdriver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver*driver, char *buf);
ssize_t (*store)(struct device_driver*driver, const char *buf, size_t count);
};
DRIVER_ATTR(_name,_mode, _show, _store)。
创建驱动属性文件:
intdriver_create_file(struct device_driver *driver,const struct driver_attribute*attr);
删除驱动属性文件:
voiddriver_remove_file(struct device_driver *driver,const struct driver_attribute*attr);
platform平台总线
设备描述结构体:platform_device
structplatform_device {
const char *name;/*设备名*/
int id;/*设备编号,配合设备名使用*/
struct device dev;
u32 num_resources;
struct resource *resource;/*设备资源*/
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
platform_device的分配:
structplatform_device *platform_device_alloc(const char *name, int id);
name设备名,id设备id,一般为-1.
添加平台设备:
intplatform_device_add(struct platform_device *pdev);
获取资源:
struct resource*platform_get_resource(struct platform_device *, unsigned int, unsigned int);dev资源所属的设备;type获取的资源类型;num获取的资源数
注册和注销设备:
intplatform_device_register(struct platform_device *);
voidplatform_device_unregister(struct platform_device *);
设备驱动结构体:platform_driver
structplatform_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 (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
注册和注销驱动程序:
intplatform_driver_register(struct platform_driver *);
voidplatform_driver_unregister(struct platform_driver *);