Linux设备模型组件-类设备-设备类及subsystem
生活随笔
收集整理的這篇文章主要介紹了
Linux设备模型组件-类设备-设备类及subsystem
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Linux設(shè)備模型??
一、sysfs文件系統(tǒng): sysfs文件系統(tǒng)是Linux2.6內(nèi)核引入的,它被看成是與proc、devfs和devpty等同類別的文件系統(tǒng),sysfs文件系統(tǒng)也是一個虛擬文件系統(tǒng),它可以產(chǎn)生一個包括所有系統(tǒng)硬件的層級視圖,與提供進(jìn)程和狀態(tài)信息的proc文件系統(tǒng)十分類似; sysfs文件系統(tǒng)把鏈接在系統(tǒng)上的所有設(shè)備和總線組織成一個分級的文件系統(tǒng),它們可以由用戶空間存取,并向用戶空間導(dǎo)出內(nèi)核數(shù)據(jù)結(jié)構(gòu)以及它們的屬性等信息.sysfs的一個目的就是展示設(shè)備驅(qū)動模型中各個組件的層次關(guān)系,其頂級目錄包括: 1、block:包含系統(tǒng)中所有的塊設(shè)備; 2、devices:包含系統(tǒng)中所有的設(shè)備,并根據(jù)設(shè)備掛載的總線類型組織成層次關(guān)系結(jié)構(gòu); 3、bus:包含系統(tǒng)中所有的總線類型; 4、drivers:包含系統(tǒng)內(nèi)核中所有已經(jīng)注冊的設(shè)備驅(qū)動程序; 5、class:包含系統(tǒng)中所有的設(shè)備類型;如,網(wǎng)卡設(shè)備、聲卡設(shè)備、輸入設(shè)備、輸出設(shè)備,等等; 二、設(shè)備模型: 從整體上描述,大概模型就如下圖所示: 從圖中可以看出,Linux設(shè)備模型就是"總線、設(shè)備、驅(qū)動、類"這四個概念之前的相互關(guān)系;這也是Linux2.6內(nèi)核抽象出來的用于管理系統(tǒng)中所有設(shè)備的模型圖; 簡單地描述設(shè)備模型的層次關(guān)系如下: 1、驅(qū)動核心中可以注冊多種類型的總線(bus_type); 2、每一種類型的總線下面可以掛載許多設(shè)備(kset,device); 3、每一種類型的總線可以使用很多設(shè)備驅(qū)動(kset,device_driver); 4、每一個驅(qū)動程序可以管理一組設(shè)備; 這種基本關(guān)系的建立源于實際系統(tǒng)中各種總線、設(shè)備、驅(qū)動、類結(jié)構(gòu)的抽象; Linux設(shè)備模型中的總線、設(shè)備、驅(qū)動和類之間環(huán)環(huán)相扣的復(fù)雜關(guān)系可以滿足內(nèi)核日益發(fā)展的的需要;對智能電源管理、熱插拔以及即插即用的支持要求也越來越高; 三、實現(xiàn): Linux2.6設(shè)備模型框架由sysfs文件系統(tǒng)、udev和內(nèi)核對象結(jié)構(gòu)kobject、kset、subsystem、bus_type、device、device_driver、class、class_device、class_interface等重量級數(shù)據(jù)結(jié)構(gòu)共同組成;這些統(tǒng)稱為Linux設(shè)備模型組件;
設(shè)備類
一、定義: 系統(tǒng)中的設(shè)備所屬的類有結(jié)構(gòu)體struct class對象來描述,用于表示某一類設(shè)備,它是一組具有共同屬性和功能的設(shè)備的抽象體,類似于面向?qū)ο笾械念惖母拍?所有的class對象都屬于class_subsys子系統(tǒng),對應(yīng)于/sys/class目錄;其結(jié)構(gòu)定義如下: struct class { const char* ? ? ? ? ? ? ? ? ? ?name; ? ? ? ? ? //類名 struct module* ? ? ? ? ? ? ? ? owner; ? ? ? ? //所屬模塊 struct subsystem ? ? ? ? ? ? ?subsys; ? ? ? ?//所屬子系統(tǒng)subsystem struct list_head ? ? ? ? ? ? ?children; ? ? ?//屬于該class類型的所有子類組成的鏈表; struct list_head ? ? ? ? ? ? ?devices; ? ? ? //屬于該class類型的所有設(shè)備class_device組成的鏈表; struct list_head ? ? ? ? ? ? ?interfaces; ? ?//類接口class_interface鏈表 struct semaphore ? ? ? ? ? ? ?sem; ? ? ? ? ? ? /* locks both the children and interfaces lists */ struct class_attribute* ? ? ? ?class_attrs; ? ? //類屬性 struct class_device_attribute* class_dev_attrs; //類設(shè)備屬性 int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size); void (*release)(struct class_device* dev); void (*class_release)(struct class* class); }; int class_register(struct class *cls):類注冊; void class_unregister(struct class *cls):類注銷; 二、設(shè)備類屬性: struct class_attribute { struct attribute attr; ssize_t (*show)(struct class* cls, char* buf); ssize_t (*store)(struct class*, const char* buf, size_t count); }; int class_create_file(struct class* cls, const struct class_attribute* attr):為指定設(shè)備類增加指定屬性; void class_remove_file(struct class* cls, const struct class_attribute* attr):刪除指定設(shè)備類上的指定屬性; 備注:struct class、struct class_attribute結(jié)構(gòu)均定義在include/linux/device.h文件中;
類設(shè)備
一、定義: 一個設(shè)備類struct class的真正目的是作為一個該類具體實例(設(shè)備)的容器使用;一個設(shè)備類的具體實例由struct class_device結(jié)構(gòu)來描述;也可以這樣理解:struct class類型相當(dāng)于面向?qū)ο笙到y(tǒng)中的類的概念,而struct class_device類型相當(dāng)于面向?qū)ο笙到y(tǒng)中的實例對象的概念;只有在應(yīng)用具體實例對象的時候,它的類才有意義;類設(shè)備struct class_device結(jié)構(gòu)定義如下: struct class_device { struct list_head ? ? ? ? ? ? ?node; struct kobject ? ? ? ? ? ? ? kobj; ? ? ? ?//內(nèi)嵌的kobject對象 struct class* ? ? ? ? ? ? ? ? ?class; ? ? ? //所屬的設(shè)備類class dev_t ? ? ? ? ? ? ? ? ? ? ? ?devt; ? ? ?//設(shè)備編號 struct class_device_attribute* devt_attr; ? //類設(shè)備屬性 struct class_device_attribute ?uevent_attr; //類設(shè)備事件屬性 struct device* ? ? ? ? ? ? ? ? dev; ? ? ? ?//如果存在,則創(chuàng)建到/sys/devices目錄下相應(yīng)入口的符號鏈接 void* ? ? ? ? ? ? ? ? ? ? ? ? ?class_data; //類私有數(shù)據(jù) struct class_device* ? ? ? ? ? parent; ? ? //父設(shè)備,即,當(dāng)前設(shè)備所附著到的設(shè)備 struct attribute_group** ? ? ? groups; ? ? /* optional groups */ void (*release)(struct class_device* dev); int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size); char ? class_id[BUS_ID_SIZE]; ? ? ? ? ? ? ? //類唯一標(biāo)識 }; 二、類設(shè)備相關(guān)函數(shù) int class_device_register(struct class_device* cd):類設(shè)備注冊; void class_device_unregister(struct class_device* cd):類設(shè)備注銷; int class_device_rename(struct class_device* cd, char* new_name):類設(shè)備重命名; void class_device_initialize(struct class_device* cd):類設(shè)備初始化; int class_device_add(struct class_device* cd):把類設(shè)備對象加入到設(shè)備模型的層次結(jié)構(gòu)中; void class_device_del(struct class_device* cd):把類設(shè)備對象從設(shè)備模型的層次結(jié)構(gòu)中刪除; struct class_device * class_device_get(struct class_device* cd):給類設(shè)備對象增加引用計數(shù); void class_device_put(struct class_device* cd):給類設(shè)備對象減少引用計數(shù); 備注:每一個設(shè)備類class對象都包含一個類設(shè)備class_device對象的鏈表,而每一個類設(shè)備class_device對象又表示一個邏輯設(shè)備,并通過類設(shè)備struct class_device結(jié)構(gòu)中的dev成員(一個指向struce device的指針)關(guān)聯(lián)到一個物理設(shè)備上;這樣,一個邏輯設(shè)備總是對應(yīng)于一個物理設(shè)備,但是,一個物理設(shè)備卻可能對應(yīng)多個邏輯設(shè)備; 三、類設(shè)備屬性: struct class_device_attribute { struct attribute attr; ssize_t (*show)(struct class_device* cls, char* buf); ssize_t (*store)(struct class_device* cls, const char* buf, size_t count); }; int class_device_create_file(struct class_device* cd, const struct class_device_attribute* attr):為指定類設(shè)備增加指定屬性; void class_device_remove_file(struct class_device* cd, const struct class_device_attribute* attr):刪除指定類設(shè)備上的指定屬性; int class_device_create_bin_file(struct class_device* cd, struct bin_attribute* attr); void class_device_remove_bin_file(struct class_device* cd, struct bin_attribute* attr); 四、類接口: 當(dāng)設(shè)備加入或離開類時,將引發(fā)class_interface中的成員函數(shù)被調(diào)用; struct class_interface { struct list_head node; struct class* ? ? class; //對應(yīng)的設(shè)備類class int (*add)(struct class_device* cd, struct class_interface* ci); ? ? //設(shè)備加入時觸發(fā) void (*remove)(struct class_device* cd, struct class_interface* ci); //設(shè)備移除時觸發(fā) }; int class_interface_register(struct class_interface* ci):類接口注冊; void class_interface_unregister(struct class_interface* ci):類接口注銷; struct class* class_create(struct module* owner, char* name):創(chuàng)建類; void class_destroy(struct class* cls):銷毀類; //創(chuàng)建類設(shè)備 struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, struct device *device, char *fmt, ...); //銷毀類設(shè)備 void class_device_destroy(struct class *cls, dev_t devt); 備注:struct class_device、struct class_device_attribute、struct class_interface結(jié)構(gòu)均定義在include/linux/device.h文件中;
Linux內(nèi)核對象---subsystem ?
一、subsystem定義: subsystem是一系列kset的集合,它用于描述系統(tǒng)中某一類設(shè)備子系統(tǒng);例如,block_subsys表示所有的塊設(shè)備,對應(yīng)于sysfs文件系統(tǒng)中的block目錄,而devices_subsys用于描述系統(tǒng)中所有的設(shè)備,對應(yīng)于sysfs文件系統(tǒng)中的devices目錄;subsystem結(jié)構(gòu)定義如下: struct subsystem { struct kset ? ? ? ? ?kset; ?//內(nèi)嵌的kset對象 struct rw_semaphore ?rwsem; //用于互斥訪問的信號量 }; 每個kset對象必須隸屬于某一個subsystem對象,通過設(shè)置kset對象結(jié)構(gòu)中的subsys字段,使之指向指定的subsystem對象,這樣就可以把一個kset對象加入到這個指定的subsystem對象中;所有掛接在同一個subsystem對象上的kset對象共享同一個rwsem信號量,用于同步訪問kset對象中的鏈表; 二、subsystem相關(guān)函數(shù): 1、void subsystem_init(struct subsystem *subsys):初始化subsystem對象; 2、int subsystem_register(struct subsystem *subsys):注冊subsystem對象; 3、void subsystem_unregister(struct subsystem *subsys)注銷subsystem對象; 4、struct subsystem *subsys_get(struct subsystem *subsys):把subsystem對象的引用計數(shù)加1; 5、void subsys_put(struct subsystem *subsys):把subsystem對象的引用計數(shù)減1; 備注:struct subsystem結(jié)構(gòu)定義于文件include/linux/kobject.h
一、sysfs文件系統(tǒng): sysfs文件系統(tǒng)是Linux2.6內(nèi)核引入的,它被看成是與proc、devfs和devpty等同類別的文件系統(tǒng),sysfs文件系統(tǒng)也是一個虛擬文件系統(tǒng),它可以產(chǎn)生一個包括所有系統(tǒng)硬件的層級視圖,與提供進(jìn)程和狀態(tài)信息的proc文件系統(tǒng)十分類似; sysfs文件系統(tǒng)把鏈接在系統(tǒng)上的所有設(shè)備和總線組織成一個分級的文件系統(tǒng),它們可以由用戶空間存取,并向用戶空間導(dǎo)出內(nèi)核數(shù)據(jù)結(jié)構(gòu)以及它們的屬性等信息.sysfs的一個目的就是展示設(shè)備驅(qū)動模型中各個組件的層次關(guān)系,其頂級目錄包括: 1、block:包含系統(tǒng)中所有的塊設(shè)備; 2、devices:包含系統(tǒng)中所有的設(shè)備,并根據(jù)設(shè)備掛載的總線類型組織成層次關(guān)系結(jié)構(gòu); 3、bus:包含系統(tǒng)中所有的總線類型; 4、drivers:包含系統(tǒng)內(nèi)核中所有已經(jīng)注冊的設(shè)備驅(qū)動程序; 5、class:包含系統(tǒng)中所有的設(shè)備類型;如,網(wǎng)卡設(shè)備、聲卡設(shè)備、輸入設(shè)備、輸出設(shè)備,等等; 二、設(shè)備模型: 從整體上描述,大概模型就如下圖所示: 從圖中可以看出,Linux設(shè)備模型就是"總線、設(shè)備、驅(qū)動、類"這四個概念之前的相互關(guān)系;這也是Linux2.6內(nèi)核抽象出來的用于管理系統(tǒng)中所有設(shè)備的模型圖; 簡單地描述設(shè)備模型的層次關(guān)系如下: 1、驅(qū)動核心中可以注冊多種類型的總線(bus_type); 2、每一種類型的總線下面可以掛載許多設(shè)備(kset,device); 3、每一種類型的總線可以使用很多設(shè)備驅(qū)動(kset,device_driver); 4、每一個驅(qū)動程序可以管理一組設(shè)備; 這種基本關(guān)系的建立源于實際系統(tǒng)中各種總線、設(shè)備、驅(qū)動、類結(jié)構(gòu)的抽象; Linux設(shè)備模型中的總線、設(shè)備、驅(qū)動和類之間環(huán)環(huán)相扣的復(fù)雜關(guān)系可以滿足內(nèi)核日益發(fā)展的的需要;對智能電源管理、熱插拔以及即插即用的支持要求也越來越高; 三、實現(xiàn): Linux2.6設(shè)備模型框架由sysfs文件系統(tǒng)、udev和內(nèi)核對象結(jié)構(gòu)kobject、kset、subsystem、bus_type、device、device_driver、class、class_device、class_interface等重量級數(shù)據(jù)結(jié)構(gòu)共同組成;這些統(tǒng)稱為Linux設(shè)備模型組件;
設(shè)備類
一、定義: 系統(tǒng)中的設(shè)備所屬的類有結(jié)構(gòu)體struct class對象來描述,用于表示某一類設(shè)備,它是一組具有共同屬性和功能的設(shè)備的抽象體,類似于面向?qū)ο笾械念惖母拍?所有的class對象都屬于class_subsys子系統(tǒng),對應(yīng)于/sys/class目錄;其結(jié)構(gòu)定義如下: struct class { const char* ? ? ? ? ? ? ? ? ? ?name; ? ? ? ? ? //類名 struct module* ? ? ? ? ? ? ? ? owner; ? ? ? ? //所屬模塊 struct subsystem ? ? ? ? ? ? ?subsys; ? ? ? ?//所屬子系統(tǒng)subsystem struct list_head ? ? ? ? ? ? ?children; ? ? ?//屬于該class類型的所有子類組成的鏈表; struct list_head ? ? ? ? ? ? ?devices; ? ? ? //屬于該class類型的所有設(shè)備class_device組成的鏈表; struct list_head ? ? ? ? ? ? ?interfaces; ? ?//類接口class_interface鏈表 struct semaphore ? ? ? ? ? ? ?sem; ? ? ? ? ? ? /* locks both the children and interfaces lists */ struct class_attribute* ? ? ? ?class_attrs; ? ? //類屬性 struct class_device_attribute* class_dev_attrs; //類設(shè)備屬性 int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size); void (*release)(struct class_device* dev); void (*class_release)(struct class* class); }; int class_register(struct class *cls):類注冊; void class_unregister(struct class *cls):類注銷; 二、設(shè)備類屬性: struct class_attribute { struct attribute attr; ssize_t (*show)(struct class* cls, char* buf); ssize_t (*store)(struct class*, const char* buf, size_t count); }; int class_create_file(struct class* cls, const struct class_attribute* attr):為指定設(shè)備類增加指定屬性; void class_remove_file(struct class* cls, const struct class_attribute* attr):刪除指定設(shè)備類上的指定屬性; 備注:struct class、struct class_attribute結(jié)構(gòu)均定義在include/linux/device.h文件中;
類設(shè)備
一、定義: 一個設(shè)備類struct class的真正目的是作為一個該類具體實例(設(shè)備)的容器使用;一個設(shè)備類的具體實例由struct class_device結(jié)構(gòu)來描述;也可以這樣理解:struct class類型相當(dāng)于面向?qū)ο笙到y(tǒng)中的類的概念,而struct class_device類型相當(dāng)于面向?qū)ο笙到y(tǒng)中的實例對象的概念;只有在應(yīng)用具體實例對象的時候,它的類才有意義;類設(shè)備struct class_device結(jié)構(gòu)定義如下: struct class_device { struct list_head ? ? ? ? ? ? ?node; struct kobject ? ? ? ? ? ? ? kobj; ? ? ? ?//內(nèi)嵌的kobject對象 struct class* ? ? ? ? ? ? ? ? ?class; ? ? ? //所屬的設(shè)備類class dev_t ? ? ? ? ? ? ? ? ? ? ? ?devt; ? ? ?//設(shè)備編號 struct class_device_attribute* devt_attr; ? //類設(shè)備屬性 struct class_device_attribute ?uevent_attr; //類設(shè)備事件屬性 struct device* ? ? ? ? ? ? ? ? dev; ? ? ? ?//如果存在,則創(chuàng)建到/sys/devices目錄下相應(yīng)入口的符號鏈接 void* ? ? ? ? ? ? ? ? ? ? ? ? ?class_data; //類私有數(shù)據(jù) struct class_device* ? ? ? ? ? parent; ? ? //父設(shè)備,即,當(dāng)前設(shè)備所附著到的設(shè)備 struct attribute_group** ? ? ? groups; ? ? /* optional groups */ void (*release)(struct class_device* dev); int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size); char ? class_id[BUS_ID_SIZE]; ? ? ? ? ? ? ? //類唯一標(biāo)識 }; 二、類設(shè)備相關(guān)函數(shù) int class_device_register(struct class_device* cd):類設(shè)備注冊; void class_device_unregister(struct class_device* cd):類設(shè)備注銷; int class_device_rename(struct class_device* cd, char* new_name):類設(shè)備重命名; void class_device_initialize(struct class_device* cd):類設(shè)備初始化; int class_device_add(struct class_device* cd):把類設(shè)備對象加入到設(shè)備模型的層次結(jié)構(gòu)中; void class_device_del(struct class_device* cd):把類設(shè)備對象從設(shè)備模型的層次結(jié)構(gòu)中刪除; struct class_device * class_device_get(struct class_device* cd):給類設(shè)備對象增加引用計數(shù); void class_device_put(struct class_device* cd):給類設(shè)備對象減少引用計數(shù); 備注:每一個設(shè)備類class對象都包含一個類設(shè)備class_device對象的鏈表,而每一個類設(shè)備class_device對象又表示一個邏輯設(shè)備,并通過類設(shè)備struct class_device結(jié)構(gòu)中的dev成員(一個指向struce device的指針)關(guān)聯(lián)到一個物理設(shè)備上;這樣,一個邏輯設(shè)備總是對應(yīng)于一個物理設(shè)備,但是,一個物理設(shè)備卻可能對應(yīng)多個邏輯設(shè)備; 三、類設(shè)備屬性: struct class_device_attribute { struct attribute attr; ssize_t (*show)(struct class_device* cls, char* buf); ssize_t (*store)(struct class_device* cls, const char* buf, size_t count); }; int class_device_create_file(struct class_device* cd, const struct class_device_attribute* attr):為指定類設(shè)備增加指定屬性; void class_device_remove_file(struct class_device* cd, const struct class_device_attribute* attr):刪除指定類設(shè)備上的指定屬性; int class_device_create_bin_file(struct class_device* cd, struct bin_attribute* attr); void class_device_remove_bin_file(struct class_device* cd, struct bin_attribute* attr); 四、類接口: 當(dāng)設(shè)備加入或離開類時,將引發(fā)class_interface中的成員函數(shù)被調(diào)用; struct class_interface { struct list_head node; struct class* ? ? class; //對應(yīng)的設(shè)備類class int (*add)(struct class_device* cd, struct class_interface* ci); ? ? //設(shè)備加入時觸發(fā) void (*remove)(struct class_device* cd, struct class_interface* ci); //設(shè)備移除時觸發(fā) }; int class_interface_register(struct class_interface* ci):類接口注冊; void class_interface_unregister(struct class_interface* ci):類接口注銷; struct class* class_create(struct module* owner, char* name):創(chuàng)建類; void class_destroy(struct class* cls):銷毀類; //創(chuàng)建類設(shè)備 struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, struct device *device, char *fmt, ...); //銷毀類設(shè)備 void class_device_destroy(struct class *cls, dev_t devt); 備注:struct class_device、struct class_device_attribute、struct class_interface結(jié)構(gòu)均定義在include/linux/device.h文件中;
Linux內(nèi)核對象---subsystem ?
一、subsystem定義: subsystem是一系列kset的集合,它用于描述系統(tǒng)中某一類設(shè)備子系統(tǒng);例如,block_subsys表示所有的塊設(shè)備,對應(yīng)于sysfs文件系統(tǒng)中的block目錄,而devices_subsys用于描述系統(tǒng)中所有的設(shè)備,對應(yīng)于sysfs文件系統(tǒng)中的devices目錄;subsystem結(jié)構(gòu)定義如下: struct subsystem { struct kset ? ? ? ? ?kset; ?//內(nèi)嵌的kset對象 struct rw_semaphore ?rwsem; //用于互斥訪問的信號量 }; 每個kset對象必須隸屬于某一個subsystem對象,通過設(shè)置kset對象結(jié)構(gòu)中的subsys字段,使之指向指定的subsystem對象,這樣就可以把一個kset對象加入到這個指定的subsystem對象中;所有掛接在同一個subsystem對象上的kset對象共享同一個rwsem信號量,用于同步訪問kset對象中的鏈表; 二、subsystem相關(guān)函數(shù): 1、void subsystem_init(struct subsystem *subsys):初始化subsystem對象; 2、int subsystem_register(struct subsystem *subsys):注冊subsystem對象; 3、void subsystem_unregister(struct subsystem *subsys)注銷subsystem對象; 4、struct subsystem *subsys_get(struct subsystem *subsys):把subsystem對象的引用計數(shù)加1; 5、void subsys_put(struct subsystem *subsys):把subsystem對象的引用計數(shù)減1; 備注:struct subsystem結(jié)構(gòu)定義于文件include/linux/kobject.h
總結(jié)
以上是生活随笔為你收集整理的Linux设备模型组件-类设备-设备类及subsystem的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何学习linux设备驱动
- 下一篇: Linux内核访问外设I O资源的方式