歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux設備驅動模型

Linux設備驅動模型

日期:2017/3/1 10:22:36   编辑:Linux編程

1、Sysfs文件系統

"sysfsis a ram-based filesystem initially based on ramfs. It provides ameans to export kernel data structures, their attributes, and thelinkages between them to userspace.”

Linux2.6內核引入了sysfs文件系統。sysfs被看成是與proc同類別的文件系統。sysfs把連接在系統上的設備和總線組織成分級的文件,使其從用戶空間可以訪問到。

Sysfs被加載在 /sys/目錄下,它的子目錄包括:

1)Block:在系統中發現的每個塊設備在該目錄下對應一個子目錄。每個子目錄中

又包含一些屬性文件,它們描述了這個塊設備的各方面屬性,如:設備大小。(loop塊設備是使用文件來模擬的)

2)Bus:在內核中注冊的每條總線在該目錄下對應一個子目錄,如: ide pci scsi usbpcmcia 其中每個總線目錄內又包含兩個子目錄:devices和drivers ,devices目錄包含了在整個系統中發現的屬於該總線類型的設備,drivers目錄包含了注冊到該總線的所有驅動。

3)Class:將設備按照功能進行的分類,如/sys/class/net目錄下包含了所有網絡接口。

4)Devices:包含系統所有的設備。

5)Kernel:內核中的配置參數

6)Module:系統中所有模塊的信息

7)Firmware:系統中的固件

8)Fs:描述系統中的文件系統

9)Power:系統中電源選項

2、K object

實現了基本的面向對象管理機制,是構成Linux2.6設備模型的核心結構。它與sysfs文件系統緊密相連,在內核中注冊的每個kobject對象對應sysfs文件系統中的一個目錄。類似於C++中的基類,Kobject常被嵌入於其他類型(即:容器)中。如bus,devices,drivers都是典型的容器。這些容器通過kobject連接起來,形成了一個樹狀結構。

structk object {

constchar

*name;

structlist_head

entry;

structkobject

*parent;//指向父對象

structkset

*kset;

structkobj_type

*ktype;

structsysfs_dirent *sd;

structkref

kref;//對象引用計數

unsignedint state_initialized:1;

unsignedint state_in_sysfs:1;

unsignedint state_add_uevent_sent:1;

unsignedint state_remove_uevent_sent:1;

};

3、Kobject操作

1)voidkobject_init(struct kobject * kobj)初始化kobject結構

2)intkobject_add(struct kobject * kobj)將kobject對象注冊到Linux系統

3)intkobject_init_and_add(struct kobject *kobj, struct kobj_type*ktype,struct kobject *parent, const char *fmt, ...)初始化kobject,並將其注冊到linux系統


4)voidkobject_del(struct kobject * kobj)從Linux系統中刪除kobject對象

5)structkobject *kobject_get(struct kobject*kobj)將kobject對象的引用計數加1,同時返回該對象指針。

6)voidkobject_put(struct kobject *kobj)將kobject對象的引用計數減1,如果引用計數降為0,則調用release方法釋放該kobject對象。

4、 Struct kobj_type


Kobject的ktype成員是一個指向kobj_type結構的指針, 該結構中記錄了kobject對象的一些屬性。

structkobj_type {

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

structsysfs_ops *sysfs_ops;

structattribute **default_attrs;

};

release:用於釋放kobject占用的資源,當kobject的引用計數為0時被調用。

5、Struct attribute

structattribute {

char *name; /*屬性文件名*/

structmodule * owner;

mode_tmode; /*屬性的保護位*/

};

struct attribute (屬性):對應於kobject的目錄下的一個文件,Name成員就是文件名。

6、Struct sysfs_ops

structsysfs_ops

{

ssize_t(*show)(struct kobject *, struct attribute *,char *);

ssize_t(*store)(struct kobject *,struct attribute *,const char *,

size_t);

};

1)Show:當用戶讀屬性文件時,該函數被調用,該函數將屬性值存入buffer中返回給用戶態;

2)Store:當用戶寫屬性文件時,該函數被調用,用於存儲用戶傳入的屬性值。

7、 kobject實例分析

kobject.c源碼

#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");

/*聲明release、show、store函數*/


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

/*對應於kobject的目錄下的一個文件,Name成員就是文件名*/
struct attribute test_attr = {
.name = "kobj_config",
.mode = S_IRWXUGO,
};

static struct attribute *def_attrs[] = {
&test_attr,
NULL,
};

/kobject對象的操作
struct sysfs_ops obj_test_sysops =
{
.show = kobj_test_show,
.store = kobj_test_store,
};

/*定義kobject對象的一些屬性及對應的操作*/
struct kobj_type ktype =
{
.release = obj_test_release,
.sysfs_ops=&obj_test_sysops,
.default_attrs=def_attrs,
};

/*release方法釋放該kobject對象*/
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;//聲明kobject對象

static int kobj_test_init(void)
{
printk("kboject test init.\n");
kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");//初始化kobject對象kobj,並將其注冊到linux系統
return 0;
}

static void kobj_test_exit(void)
{
printk("kobject test exit.\n");
kobject_del(&kobj);
}

module_init(kobj_test_init);

module_exit(kobj_test_exit);

Copyright © Linux教程網 All Rights Reserved