Path for Linux Device Driver engineers-device model (top) Underlying model

Source: Internet
Author: User

Path for Linux Device Driver engineers-device model (top) Underlying model

K-style

Reprinted please indicate from Hengyang Normal University 08 electric 2 Y-kee http://blog.csdn.net/ayangke,QQ:843308498

 

I. Important knowledge points

 

1. sysfs File System

The sysfs file system is a special file system similar to the proc file system. It exists in the memory and is mounted to the memory by the kernel when the system is started. Organizes devices in the system into hierarchies and provides detailed data structure information to user mode programs.

 

2. Underlying model of Linux Devices

 

1) Why use the device model?

As the topological structure of the system becomes more complex and new features such as power management need to be supported, a device model appears in the 2.6 kernel. The device model is actually a set of data structures. The kernel uses this model to support a variety of tasks, including:

A. Power Management and System Shutdown

The device model enables the operating system to traverse system hardware in the correct order.

B. Communication with user space

The sysfs file system provides the user space with system information and changes the structure of operation parameters.

C. Hot swapping events

D. device type

Many parts of the system are not interested in how devices are connected, but they need to know which types of devices are available. The device model provides a mechanism to classify devices.

E. Object Lifecycle

Many of the above features, including hot swapping support and sysfs, make the management of objects in the kernel more complex. The device model needs to create a mechanism to manage the object lifecycle.

 

2) kobject

If the device model is a house, kobject is the building block. Each registered kobject corresponds to a directory in the sysfs file system. Kobject is the basic structure of the device model. Similar to the basic class of C ++, it is embedded in a larger object, the so-called container, used to describe the components of the device model. Such as bus, device, and drivers are typical containers. These containers are connected through kobject to form a tree structure. The tree structure corresponds to the/sys file system. However, kobject can only create a single-layer structure, that is, it can only create a level-1 directory. To create a multi-level directory, you must also use the kset described later.

The kobject structure is defined:

Struct kobject {

Char * k name; pointer to device name

Char name [kobj name len]; device name

Struct kref; object reference count

Struct list head entry; mounted to the Unit in the kset

Struct kobject * parent; pointer to parent object

Struct kset * kset; pointer to the kset

Struct kobj type * ktype; pointer to its object type descriptor

Struct dentry * dentry; file Node path pointer corresponding to this object in sysfs File System

};

Related operation functions:

Void kobjet_init (struct kobject * kobj)

Initialize kobject

Int kobject_add (struct kobject * kobj)

Register the kobject object to the Linux system. If the object fails, an error code is returned.

Int kobject_init_and_add (structkobject * kobj, kobj_type * ktype, struct kobject * parent, const * FMT ...)

Initialize and register the kobject. The kobject object to be initialized is passed in. ktype will be introduced later. Parent points to the kobject object of the upper level. If it refers to null, A directory will be created at the top layer of/sys. * FMT is the name of the kobject object.

The ktype object of kobject is a pointer to the kobject_type structure, which records some attributes of the kobject object. Each kobject must correspond to a corresponding kobject structure.

Struct kobj_type {

Void (* release) (struct kobject * kobj );

Structsysfs_ops * sysfs_ops;

Structattribute ** default_attrs;

};

The release method is used to release the resources occupied by kobject. It is called when the reference count of kobject is 0.

Attribute member of kobje_type:

Struct attribute {

Char * Name; // attribute file name

Structmodule * owner;

Mode_tmode;

}

Struct attribute: corresponds to the next file in the kobject directory. Name is the file name.

Struct sysfs_ops member of kobje_type:

Struct sysfs_ops

{

Ssize_t (* Show) (structkobejct *, struct attribute *, char * Name );

Ssize_t (* store) (structkobejct *, struct attribute *, char * Name );

}

Show: when a user reads a property file, this function is called. This function saves the property value to the buffer and returns it to the user State;

Store: when a user writes an attribute file, this function is called to store the attribute values stored by the user.

Kobject test module:

#include <linux/device.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/string.h>#include <linux/sysfs.h>#include <linux/stat.h> MODULE_AUTHOR("David Xie");MODULE_LICENSE("Dual BSD/GPL"); void obj_test_release(struct kobject *kobject);ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf);ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count); struct attribute test_attr = {        .name = "kobj_config",        .mode = S_IRWXUGO,}; static struct attribute *def_attrs[] = {        &test_attr,        NULL,};  struct sysfs_ops obj_test_sysops ={        .show = kobj_test_show,        .store = kobj_test_store,}; struct kobj_type ktype = {        .release = obj_test_release,        .sysfs_ops=&obj_test_sysops,        .default_attrs=def_attrs,}; void obj_test_release(struct kobject *kobject){        printk("eric_test: release .\n");} ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr,char *buf){        printk("have show.\n");        printk("attrname:%s.\n", attr->name);        sprintf(buf,"%s\n",attr->name);        return strlen(attr->name)+2;} ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count){        printk("havestore\n");        printk("write: %s\n",buf);        return count;} struct kobject kobj;static int kobj_test_init(){        printk("kboject test init.\n");        kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");        return 0;} static int kobj_test_exit(){        printk("kobject test exit.\n");        kobject_del(&kobj);        return 0;} module_init(kobj_test_init);module_exit(kobj_test_exit);

Test results:

The kobject_test directory is created under the/sys directory.

The kobj_config file is in the kobject_test directory.

Read the kobject_config file and call the show function. The name of the kobject object returned by show is displayed in the user space.

The store function is called by writing the kobject_config file.

 

3) kset

The main function of kset is tolerance. We can think of it as the top-level container of kobject. In fact, each kset object contains its own kobject, and multiple methods can be used to process the kset. If kobject is a base class, kset is a delivery class. Kobject is organized into hierarchical structures through kset. kset is a combination of the same types. In general, kobject creates a level-1 sub-directory, and kset can create a level-1 parent directory for kobject.

Struct kset {

Struct subsystem * subsys; pointer to the subsystem

Struct kobj type * ktype; pointer to the kset object type descriptor

Struct list head list; used to connect the chain table headers of all kobject in the kset

Struct kobject kobj; embedded kobject

Struct kset_uevent_ops * uevent_ops; pointer to hot swapping operation table

};

All the kobject contained in the kset is organized into a bidirectional cyclic linked list. The list field is the header of the linked list. The ktype field points to a kobj type structure, which is shared by all the kobject in the kset, indicating the type of these objects. The kset data structure is also embedded with a kobject object (represented by the kobj domain). The parent fields of all the kobject objects belonging to this kset point to this embedded object. In addition, kset depends on kobj to maintain reference count: kset reference count is actually the reference count of the embedded kobject object.

Relationship between kset and kobject

 

Kset operation:

Int kset_register (struct kset * kset)

Register kset

Void kset_unregister (struct kset * kset)

Log out of kset

Hot swapping event: in Linux, when the system configuration changes, such as adding kset to the system or moving kobject, a notification will be sent from the kernel space to the user space, which is a hot swapping event. Hot swapping events can cause calls of handlers (such as udev and mdev) in the user space. These handlers respond to hot swapping events by loading drivers, creating device nodes, and so on.

The actual control over hot swapping events is completed by the functions in the struct kset_uevent_ops structure.

Struct kset_uevnt_ops {

INT (* filter) (struct kset * kset, struct kobject * kobj );

Const char * (* Name) (struct kset * kset, struct kobject * kobj );

INT (* uevent) (struct kset * kset, struct kobject * kobj, struct kobj_uevent * env );

}

Filter determines whether an event is generated. If 0 is returned, no event is generated.

Name to pass a suitable string to the user space

Uevent transmits the information required by any hot swapping script through environment variables. It will provide the opportunity to add environment variables before calling (udev or mdev.

 

Kset test module:

#include <linux/device.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/string.h>#include <linux/sysfs.h>#include <linux/stat.h>#include <linux/kobject.h> MODULE_AUTHOR("David Xie");MODULE_LICENSE("Dual BSD/GPL"); struct kset kset_p;struct kset kset_c;int kset_filter(struct kset *kset, struct kobject *kobj){        printk("Filter: kobj %s.\n",kobj->name);        return 1;} const char *kset_name(struct kset *kset, struct kobject *kobj){        static char buf[20];        printk("Name: kobj %s.\n",kobj->name);        sprintf(buf,"%s","kset_name");        return buf;} int kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env){        int i = 0;        printk("uevent: kobj %s.\n",kobj->name);        while( i < env->envp_idx){                printk("%s.\n",env->envp[i]);                i++;        }        return 0;}struct kset_uevent_ops uevent_ops = {        .filter = kset_filter,        .name   = kset_name,        .uevent = kset_uevent,}; int kset_test_init(){        printk("kset test init.\n");        kobject_set_name(&kset_p.kobj,"kset_p");        kset_p.uevent_ops = &uevent_ops;        kset_register(&kset_p);         kobject_set_name(&kset_c.kobj,"kset_c");        kset_c.kobj.kset = &kset_p;        kset_register(&kset_c);        return 0;} int kset_test_exit(){        printk("kset test exit.\n");        kset_unregister(&kset_p);        kset_unregister(&kset_c);        return 0;} module_init(kset_test_init);module_exit(kset_test_exit);

Test results:

It can be seen that when the kset is loaded, A kset_p is created under/sys, and kset_c is created under kset_p. Hot swapping occurs when the kset module is loaded and detached.

 

Reference books:

I'm sysfs about Linux.

Linux Device Drivers (Third edition)

China embedded Courseware

 

PS:

Please refer to the next article "path for Linux Device Driver engineers-device model (bottom) Upper Layer Model"

I am exhausted by writing this stuff.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.