I am writing this notes from Linux device drivers book(LKD)
-The demands of newer systems, with their more complicated topologies and need to support features such as power management, made it clear, however, that a general abstraction describing the structure of the system was needed.
-device model provides that abstraction
1)Power management and system shutdown
2)Communications with user space
3)Hotpluggable devices
4)Device classes
5)Object lifecycles
Koject
- It was initially conceived as a simple reference counter, but its responsibilities have grown over time, and so have its fields.
The tasks handled by struct kobject and its supporting code now include:
1)Reference counting of objects
2)Sysfs representation
3)Data structure glue
4)Hotplug event handling
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;
};
Embedding kobjects
- kobjects are used to control access to a larger, domain-specific object. To this end, kobjects are found embedded in other structures
- If you are used to thinking of things in object-oriented terms, kobjects can be seen as a top-level, abstract class from which other classes are derived.
struct cdev {
struct kobject kobj;
struct module *owner;
struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
Kobject initialization
-step 1 simply set the entire kobject to 0
-step 2 void kobject_init(struct kobject *kobj);
kobject_init sets the kobject’s reference count to one.
-step 3(minimum set the name) int kobject_set_name(struct kobject *kobj, const char *format, ...);
Reference count manipulation
-struct kobject *kobject_get(struct kobject *kobj);
-void kobject_put(struct kobject *kobj);
Sometimes only refreance count does not work. We also need existent of module that created the koject. It would not do to unload that module while the kobject is still
being passed around.
Release functions and kobject types
- what happens to a kobject when its reference count reaches 0.
- The code that created the kobject generally does not know when that will happen
If it know than there would be no point in reference count.
-user-space programs can keep a reference to a kobject (by keeping one of its associated sysfs files open) for an arbitrary period of time.
- The reference count is not under the direct control of the code that created the kobject.
- So that code must be notified asynchronously whenever the last reference to one of its kobjects goes away
-This notification is done through a kobject’s release method.
-every kobject must have a release method.
- the release method is not stored in the kobject itself; instead, it is associated with the type of the structure that contains the kobject.
struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
-Confusingly, the pointer to this structure can be found in two different places. The kobject structure itself contains a field (called ktype) that can contain this pointer.
If, however, this kobject is a member of a kset, the kobj_type pointer is provided by that kset instead.
macro:
struct kobj_type *get_ktype(struct kobject *kobj);
finds the kobj_type pointer for a given kobject.
Kobject Hierarchies, Ksets, and Subsystems
-The kobject structure is often used to link together objects into a hierarchical struc-
ture that matches the structure of the subsystem being modeled.
-there are two separate mechanize,parent pointer and kset.
eg. for example, a kobject represents a USB device, its parent pointer may indicate the object representing the hub into which the device is plugged.
-The main use for the parent pointer is to position the object in the sysfs hierarchy.
Ksets-a kset is a collection of kobjects embedded within structures of the same type.
- The two concepts have been separated so that objects of identical type can appear in distinct sets.
- the main function of a kset is containment.
- In fact, each kset contains its own kobject internally, and it can, in many ways, be treated the same way as a kobject.
-It is worth noting that ksets are always represented in sysfs; once a kset has been set up and added to the system, there will be a sysfs directory for it. Kobjects do not necessarily show up in sysfs, but every kobject that is a member of a kset is represented there.
-Adding a kobject to a kset
step1: The kobject’s kset field must be pointed at the kset of interest;
step2:then
int kobject_add(struct kobject *kobj);
-extern int kobject_register(struct kobject *kobj);
This function is simply a combination of kobject_init and kobject_add.
-When a kobject is passed to kobject_add, its reference count is incremented
-kobject will probably have to be removed from the kset to clear that reference;
void kobject_del(struct kobject *kobj);
-There is also a kobject_unregister function, which is a combination of kobject_del and kobject_put.
-kset keeps its children in standard link list,in most of the case kobject in the kset as pointer pointing to kset in parent field of the kobject.
Operations on ksets
-void kset_init(struct kset *kset);
int kset_add(struct kset *kset);
int kset_register(struct kset *kset);
void kset_unregister(struct kset *kset);
-To manage the reference count of kset
struct kset *kset_get(struct kset *kset);
void kset_put(struct kset *kset);
- kset also has a name, which is stored in the embedded kobject
kobject_set_name(&my_set->kobj, "The name");
Subsystems- Subsystems usually (but not always) show up at the top of the sysfs hierarchy.
If probleby you want to create a new subsystem that means you need to create new class
A subsystem is represented by a simple structure:
struct subsystem {
struct kset kset;
struct rw_semaphore rwsem;
};
-subsystem is just a wrapper around a kset with a semaphore thrown in it.
Subsystems are often declared with a special macro:
-decl_subsys(name, struct kobj_type *type,struct kset_hotplug_ops *hotplug_ops);
Subsystems have the usual list of setup and teardown functions:
-void subsystem_init(struct subsystem *subsys);
-int subsystem_register(struct subsystem *subsys);
-void subsystem_unregister(struct subsystem *subsys);
-struct subsystem *subsys_get(struct subsystem *subsys)
-void subsys_put(struct subsystem *subsys);
Low-Level Sysfs Operations-Kobjects are the mechanism behind the sysfs virtual filesystem. For every directory
found in sysfs, there is a kobject lurking somewhere within the kernel.
-Every kobject of interest also exports one or more attributes.
-try to look at this <linux/sysfs.h>.
This section examines how kobjects and sysfs interact at a low level.
- kobject to show up in sysfs is simply a matter of calling kobject_add.
-Sysfs entries for kobjects are always directories, so a call to kobject_add results in
the creation of a directory in sysfs.
-The name assigned to the kobject (with kobject_set_name) is the name used for
the sysfs directory.
- The sysfs entry is located in the directory corresponding to the kobject’s parent
pointer.
Default Attributesstruct kobj_type
{
void (*release)(struct kobject *);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
struct attribute
{
char *name;//name is the name of the attribute
struct module *owner;//pointer to the module that is responsible for implementation of this attribute
mode_t mode;//projection bit appilted to this attribute
};
-default_attrs array says what the attributes are but does not tell sysfs how to actually implement those attributes.
-That task falls to the kobj_type->sysfs_ops field,
which points to a structure defined as:
struct sysfs_ops {
ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
char *buffer);
ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t size);
};
-The demands of newer systems, with their more complicated topologies and need to support features such as power management, made it clear, however, that a general abstraction describing the structure of the system was needed.
-device model provides that abstraction
1)Power management and system shutdown
2)Communications with user space
3)Hotpluggable devices
4)Device classes
5)Object lifecycles
Koject
- It was initially conceived as a simple reference counter, but its responsibilities have grown over time, and so have its fields.
The tasks handled by struct kobject and its supporting code now include:
1)Reference counting of objects
2)Sysfs representation
3)Data structure glue
4)Hotplug event handling
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;
};
Embedding kobjects
- kobjects are used to control access to a larger, domain-specific object. To this end, kobjects are found embedded in other structures
- If you are used to thinking of things in object-oriented terms, kobjects can be seen as a top-level, abstract class from which other classes are derived.
struct cdev {
struct kobject kobj;
struct module *owner;
struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
Kobject initialization
-step 1 simply set the entire kobject to 0
-step 2 void kobject_init(struct kobject *kobj);
kobject_init sets the kobject’s reference count to one.
-step 3(minimum set the name) int kobject_set_name(struct kobject *kobj, const char *format, ...);
Reference count manipulation
-struct kobject *kobject_get(struct kobject *kobj);
-void kobject_put(struct kobject *kobj);
Sometimes only refreance count does not work. We also need existent of module that created the koject. It would not do to unload that module while the kobject is still
being passed around.
Release functions and kobject types
- what happens to a kobject when its reference count reaches 0.
- The code that created the kobject generally does not know when that will happen
If it know than there would be no point in reference count.
-user-space programs can keep a reference to a kobject (by keeping one of its associated sysfs files open) for an arbitrary period of time.
- The reference count is not under the direct control of the code that created the kobject.
- So that code must be notified asynchronously whenever the last reference to one of its kobjects goes away
-This notification is done through a kobject’s release method.
-every kobject must have a release method.
- the release method is not stored in the kobject itself; instead, it is associated with the type of the structure that contains the kobject.
struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
-Confusingly, the pointer to this structure can be found in two different places. The kobject structure itself contains a field (called ktype) that can contain this pointer.
If, however, this kobject is a member of a kset, the kobj_type pointer is provided by that kset instead.
macro:
struct kobj_type *get_ktype(struct kobject *kobj);
finds the kobj_type pointer for a given kobject.
Kobject Hierarchies, Ksets, and Subsystems
-The kobject structure is often used to link together objects into a hierarchical struc-
ture that matches the structure of the subsystem being modeled.
-there are two separate mechanize,parent pointer and kset.
eg. for example, a kobject represents a USB device, its parent pointer may indicate the object representing the hub into which the device is plugged.
-The main use for the parent pointer is to position the object in the sysfs hierarchy.
Ksets-a kset is a collection of kobjects embedded within structures of the same type.
- The two concepts have been separated so that objects of identical type can appear in distinct sets.
- the main function of a kset is containment.
- In fact, each kset contains its own kobject internally, and it can, in many ways, be treated the same way as a kobject.
-It is worth noting that ksets are always represented in sysfs; once a kset has been set up and added to the system, there will be a sysfs directory for it. Kobjects do not necessarily show up in sysfs, but every kobject that is a member of a kset is represented there.
-Adding a kobject to a kset
step1: The kobject’s kset field must be pointed at the kset of interest;
step2:then
int kobject_add(struct kobject *kobj);
-extern int kobject_register(struct kobject *kobj);
This function is simply a combination of kobject_init and kobject_add.
-When a kobject is passed to kobject_add, its reference count is incremented
-kobject will probably have to be removed from the kset to clear that reference;
void kobject_del(struct kobject *kobj);
-There is also a kobject_unregister function, which is a combination of kobject_del and kobject_put.
-kset keeps its children in standard link list,in most of the case kobject in the kset as pointer pointing to kset in parent field of the kobject.
Operations on ksets
-void kset_init(struct kset *kset);
int kset_add(struct kset *kset);
int kset_register(struct kset *kset);
void kset_unregister(struct kset *kset);
-To manage the reference count of kset
struct kset *kset_get(struct kset *kset);
void kset_put(struct kset *kset);
- kset also has a name, which is stored in the embedded kobject
kobject_set_name(&my_set->kobj, "The name");
Subsystems- Subsystems usually (but not always) show up at the top of the sysfs hierarchy.
If probleby you want to create a new subsystem that means you need to create new class
A subsystem is represented by a simple structure:
struct subsystem {
struct kset kset;
struct rw_semaphore rwsem;
};
-subsystem is just a wrapper around a kset with a semaphore thrown in it.
Subsystems are often declared with a special macro:
-decl_subsys(name, struct kobj_type *type,struct kset_hotplug_ops *hotplug_ops);
Subsystems have the usual list of setup and teardown functions:
-void subsystem_init(struct subsystem *subsys);
-int subsystem_register(struct subsystem *subsys);
-void subsystem_unregister(struct subsystem *subsys);
-struct subsystem *subsys_get(struct subsystem *subsys)
-void subsys_put(struct subsystem *subsys);
Low-Level Sysfs Operations-Kobjects are the mechanism behind the sysfs virtual filesystem. For every directory
found in sysfs, there is a kobject lurking somewhere within the kernel.
-Every kobject of interest also exports one or more attributes.
-try to look at this <linux/sysfs.h>.
This section examines how kobjects and sysfs interact at a low level.
- kobject to show up in sysfs is simply a matter of calling kobject_add.
-Sysfs entries for kobjects are always directories, so a call to kobject_add results in
the creation of a directory in sysfs.
-The name assigned to the kobject (with kobject_set_name) is the name used for
the sysfs directory.
- The sysfs entry is located in the directory corresponding to the kobject’s parent
pointer.
Default Attributesstruct kobj_type
{
void (*release)(struct kobject *);
struct sysfs_ops *sysfs_ops;
struct attribute **default_attrs;
};
struct attribute
{
char *name;//name is the name of the attribute
struct module *owner;//pointer to the module that is responsible for implementation of this attribute
mode_t mode;//projection bit appilted to this attribute
};
-default_attrs array says what the attributes are but does not tell sysfs how to actually implement those attributes.
-That task falls to the kobj_type->sysfs_ops field,
which points to a structure defined as:
struct sysfs_ops {
ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
char *buffer);
ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t size);
};
No comments:
Post a Comment