Linux Device Driver Model

Source: Internet
Author: User

Linux systems integrate devices and drivers into device-driven models to manage

Device driver Features:

1, initialization and release of hardware devices

2, manage the device, including the parameter setting, and provide the unified operation interface to the device.

3. Read the data that the application passes to the device file or the loopback application requests

4. Detect or process errors in the device

The device-driven model provides a hardware abstraction including:

1, Power management

In fact, power management is the time when some equipment is not working, let it rest for a while, sleep for a while (minimum consumption), to achieve the purpose of saving electricity

One of its important features is:

Power-down mode to suspend devices in the system in a certain order

In full-speed operation mode, the system's equipment will be resumed in a certain sequence.

That means, a bus has n devices, only when n devices are suspended, the bus can hang. However, as long as one device is restored, the bus has to be restored

2, Plug and Play device support

This everyone has deep experience, you put PS/2 mouse, keyboard pull out, and then plug it up, to see if there is no response. But pull the USB mouse keyboard and plug it in, you can continue to use

This is the legendary plug-and-play support.

3, communication with user space

There are many ways to communicate with users, and the previously famous proc file system is a stark representation. It gives the user a pair of clairvoyance. But proc still by the later Sysfs file system to take down, from now on.

Although Proc is still alive, its influence has fallen. At the same time have to say, Proc got the world, certainly has its extraordinary place, where SYSFS may be frustrated. But the strong is still not so good to shake

The Linux device driver model has several basic data structure models: Kobject,kset,subsystem

Kobject: This is the basis of the device-driven model, like a floor tile and bricks. Sysfs was his offspring, and his father and his grandfather propped it up.

struct Kobject

{

const char *name; Names that appear in the SYSFS

struct List_head entry; Next Kobject structure

struct Kobject *parent; Point to the parent kobject struct, if present

struct Kset *kset; Point to Kset Collection

struct Kobj_type *ktype; Point to Kobject type descriptor

struct Sysfs_dirent *sd; File directory corresponding to Sysfs

struct Kref kref; Kobject reference count

unsigned int state_initialized:1; Whether to initialize

unsigned int state_in_sysfs:1; Whether to join SYSFS

unsigned int state_add_uevent_sent:1; is hot plug-in supported

unsigned int state_remove_uevent_sent:1; Is hot-swappable supported

}

void Kobject_init (struct kobject *kobj,struct kobj_type *ktype)

{

char * ERR_STR;

if (!kobj)

{

ERR_STR = "Invalid Kobject pointer!"

Goto error;

}

if (!ktype)

{

ERR_STR = "must has a ktype to be initialized properly!\n";

Goto error;

}

if (kobj->state_initialized)

{

PRINTK (Kern_err "Kobject (%p): tried to init an initialized"

"Object, something is seriously wrong.\n", kobj);

Dump_stack ();

}

Kobject_init_internal (Kobj); Initialize the internal members of the Kobject

Kobj->ktype = Ktype; Binding a Ktype property for Kobject

return;

Error

PRINTK (Kern_err "Kobject (%p):%s\n", KOBJ,ERR_STR);

Dump_stack ();

}

static void Kobject_init_internal (struct koject *kobj)

{

if (!kobj)

return;

Kref_init (&kobj->kerf);

Init_list_head (&kobj->entry);

KOBJ->STATE_IN_SYSFS = 0;

kobj->state_add_uevent_sent = 0;

kobj->state_remove_uevent_sent = 0;

kobj->state_initialized = 1;

}

Kernel interface:

Kobject_init (); Initiation of Kobject

Kobject_get (); Increase Kobject Reference count

Kobject_put (); Reduce Kobject reference count, Count to zero, call Kobject_release () release, it's inside Kobj_type

Kobject_set_name (); Set name

Kobject_rename (); Renaming

Kobject_add () add

    

Each kobject will have an attribute Kobj_type

struct Kobj_type

{

void (*release) (struct kobject *kobj); Releasing Kobject and other resource-intensive functions

struct Sysfs_ops *sysfs_ops; Methods for manipulating properties

struct attribute **default_attrs; Property array

};

struct attribute

{

const char *name; Name of the property

struct module *owner; Only the module that owns the property is used infrequently

mode_t mode; Property Read and Write permissions

};

struct SYSFS_OPS

{

ssize_t (*show) (struct kobject *,struct attribute *,char *); Read Property manipulation function

ssize_t (*store) (struct kobject *,struct attribute *,const char *,size_t); Write Property manipulation functions

};

struct Kobject *kobject_get (struct kobject *kobj)

{

if (kobj)

Kref_get (&kobj->kerf);

return kobj;

}

void Kobject_put (struct kobject *kobj)

{

if (kobj)

{

if (!kobj->state_initialized)

WARN (1,kern_warning "Kobject: '%s ' (%p): Is isn't Initialized,yet kobject_put () is being called.\n", Kobject_name (Kobj), Kobj);

Kref_put (&kobj->kref,kobject_release);

}

}

Typically, DEFAULT_ATTR members of the Kobject type define all the default properties owned by Kobjet. However, in special cases, you can add some default properties:

To add a property file:

int sysfs_create_file (struct kobject *kobj,const struct attribute *attr);

To delete a property file:

void Sysfs_remove_file (struct kobject *kobj, const struct attribute *attr);

struct Kset

{

struct List_head list; The link list header address of the Kobject object that the connection contains

spinlock_t List_lock; Maintain the spin lock for list lists

struct Kobject kobj; Inline Kobject, indicating that Kset itself is also a directory

struct Kset_uevent_ops *uevent_ops; Hot Swap Events

};

struct KSET_UEVENT_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_ent *env);

};

Kset and Kobject relations:

The 1,kset collection contains the kobject structure that belongs to it, and the Kset.list list is used to connect the first and last Kobject objects. The first Kobject uses entry to connect the Kset collection and the second Kobject object. The second Kobject object uses entry to connect the first Kobject object and the third Kobject object, and so on, and eventually forms a linked list of Kobject objects.

2, the parent pointer of all kobject structures points to the Kobject object that kset contains, forming a parent-child hierarchical relationship

All Kset pointers to 3,kobject point to the Kset collection that contains it, so kset collections can be easily found by Kobject objects

4,kobject's kobj_type pointer points to its own kobj_type, and each kobject has a separate kobj_type structure. In addition, there is also a kobject structure in the Kset collection, and the xxx of the struct also points to a kobj_type structure. It is known that a set of properties and the methods of manipulating properties are defined in Kobj_type. Note here: The priority of Kobj_type in Kset is higher than the priority of Kobj_type in Kobject object. If two kobj_type are present, then the function in Kset is called first. If Kobj_type in Kset is empty, the function in Kobj_type corresponding to each kobject struct itself is called

The Kobj in 5,kset is also responsible for the reference count of Kset

Kset operation

void Kset_init (struct kset *k)//initialization

{

Kobject_init_internal (&k->kobj);

Init_list_head (&k->list);

Spin_lock_init (&k->list_lock);

}

int Kset_register (struct kset *k); Registration function

void Kset_unregister (struct kset *k); Logoff function

Static inline struct Kset *kset_get (struct kset *k);

static inline void Kset_put (struct kset *k);

Three components of a device-driven model

Bus:

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,struct device_driver *drv);

Int (*uevent) (struct device *dev,struct kobj_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 (*suspend_late) (struct device *dev,pm_message_t state);

Int (*resume_early) (struct device *dev);

  

struct Dev_pm_ops *pm;

struct Bus_type_private *p;

};

struct bus_type_private

{

struct Kset Subsys; Represents the bus subsystem, where the kobj is the bus's main kobj, which is the top level

struct Kset *drivers_kset; Mounts to all drive sets on the bus

struct Kset * devices_kset; Mounts to all device collections on the bus

struct Klist klist_devices; List of all devices

struct Klist klist_drivers; List of all drivers

struct Block_notifier_head bus_notifier;

unsigned int drivers_autoprobe:1; Set whether the driver registration is, automatically eject the device

struct Bus_type *bus; Point back to the bus containing itself

};

int Bus_register (struct bus_type *bus);

void Bus_unregister (struct bus_type *bus);

struct Bus_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);

};

int bus_create_file (struct bus_type *bus,struct bus_attribute *attr);

void Bus_remove_file (struct bus_type *bus,struct bus_attribute *attr);

Equipment:

struct device

{

struct Klist klist_children; Linked list of connected sub-devices

struct device *parent; Pointer to parent device

struct Kobject kobj; Built-in Kobject

Char Bus_id[bus_id_size]; Connecting to a location on the bus

unsigned uevent_supress:1; Whether hot-swappable events are supported

const char *init_name; Initialization name of the device

struct Device_type *type; Special processing functions related to equipment

struct Bus_type *bus; The bus pointer to the connection

struct Device_driver *driver; Drivers that point to the device

void *driver_data; Pointers to driver private data

struct Dev_pm_info power; Power Management Information

dev_t devt; Device number

struct class *class; Pointing to the class the device belongs to

struct Attribute_group **groups; Group Properties for Devices

void (*release) (struct device *dev); Release the callback function for the device descriptor

...

};

int device_register (struct device *dev);

void Device_unregister (struct device *dev);

struct Device_attribute

{

struct attribute attr;

ssize_t (*show) (struct device *dev,struct device_attribute *attr,char *buf);

ssize_t (*store) (struct device *dev,struct device_attribute *attr,const char *buf,size_t count);

};

int device_create_file (struct device *device,struct device_attribute);

void Device_remove_file (struct device *dev,struct device_attribute *attr);

Driven:

struct Device_driver

{

const char *name; Device driver name

struct Bus_type *bus; The bus that points to the drive, there are many devices on the bus

struct module *owner; Device driver Self-module

const char *mod_name; Device driver name

Int (*probe) (struct device *dev); /Probe function

Int (*remove) (struct device *dev);

void (*shutdown) (struct device *dev);

Int (*suspend) (struct device *dev,pm_message_t state);

Int (*resume) (struct device *dev);

struct Attribute_group **group;

struct Dev_pm_ops *pm;

struct Driver_private *p;

};

struct driver_private

{

struct Kobject kobj; Built-in kobject structure for building device driver models

struct Klist klist_devices; All device linked lists supported by this driver

struct Klist_node Knode_bus; The driver belongs to the bus

struct Module_kobject *mkobj; Driver-driven modules

struct Device_driver *driver; Point to the drive itself

};

int Driver_register (struct device_driver *drv);

void Driver_unregister (struct device_driver *drv);

struct Driver_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);

};

int driver_create_file (struct device_driver *drv,struct driver_attribute *attr);

void Driver_remove_file (struct device_driver *drv,struct driver_attribute *attr);

Linux Device Driver Model

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.