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