Linux設備管理(三):sysfs文件系統的功能及其應用

/************************************************************************************html

*本文爲我的學習記錄,若有錯誤,歡迎指正。node

*本文參考資料:linux

*        http://www.wowotech.net/linux_kenrel/dm_sysfs.html框架

*        https://blog.csdn.net/skyflying2012/article/details/11783847學習

*        http://www.cnblogs.com/xiaojiang1025/p/6202298.html
spa

*        http://www.wowotech.net/linux_kenrel/dm_sysfs.html.net

************************************************************************************/設計

1. sysfs的簡介

sysfs是一個基於ramfs的文件系統,在2.6內核開始引入,用來導出內核對象(kernel object)的數據、屬性到用戶空間,以文件目錄結構的形式爲用戶空間提供對這些數據、屬性的訪問支持。指針

從驅動開發的角度,/sysfs爲用戶提供了除了設備文件/dev和/proc以外的另一種經過用戶空間訪問內核數據的方式。使用sysfs,編譯內核的時候須要定義CONFIG_SYSFS,能夠經過mount -t sysfs sysfs /sys命令來掛載sysfs到"/sys"目錄。code

2. sysfs的目錄結構

/sys

/sys/block/

塊設備的存放目錄,這是一個過期的接口,按照sysfs的設計理念,全部的設備都存放在"sys/devices/"同時在"sys/bus/"或(和)"sys/class/"存放相應的符號連接,因此如今這個目錄只是爲了提升兼容性的設計,裏面的文件已經被所有替換成了符號連接,只有在編譯內核的時候勾選CONFIG_SYSFS_DEPRECATED纔會有這個目錄。

/sys/bus/

bus包含了系統中全部的總線,每一種總線一般還有兩個子目錄:device和driver。

/sys/class/

按照設備功能對系統設備進行分類的結果放在這個目錄,如系統全部輸入設備都會出如今 "/sys/class/input"之下。和sys/bus同樣,sys/class最終的文件都是符號連接,這樣設備能夠保證整個系統中每個設備都只有一個實例。

/sys/dev/

按照設備號對字符設備和塊設備進行分類的結果放在這個目錄,一樣,文件依然是使用符號連接的形式連接到"sys/devices/"中的相應文件。

/sys/devices

全部的設備文件實例都在"sys/devices/"目錄下。

/sys/fs

這裏按照設計是用於描述系統中全部文件系統,包括文件系統自己和按文件系統分類存放的已掛載點,但目前只有 fuse,gfs2 等少數文件系統支持 sysfs 接口,一些傳統的虛擬文件系統(VFS)層次控制參數仍然在 sysctl (/proc/sys/fs) 接口中。

/sys/kernel

這裏是內核全部可調整參數的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等幾項較新的設計在使用它,其它內核可調整參數仍然位於 sysctl (/proc/sys/kernel) 接口中。

/sys/module

這裏有系統中全部模塊的信息,不論這些模塊是之內聯(inlined)方式編譯到內核映像文件(vmlinuz)中仍是編譯爲外部模塊(ko文件),均可能會出如今 /sys/module 中:編譯爲外部模塊(ko文件)在加載後會出現對應的/sys/module/。

/sys/power

這裏是系統中電源選項,這個目錄下有幾個屬性文件能夠用於控制整個機器的電源狀態,如能夠向其中寫入控制命令讓機器關機、重啓等。

 "sys/class/","sys/bus/","sys/devices"是設備開發中最重要的幾個目錄。他們之間的關係能夠用下圖表示。

3.attribute

3.1 attribute的功能

在sysfs中,設備的kobject的屬性(kobject.ktype.attribute)以文件的形式被導出,sysfs還提供了使用文件I/O直接修改內核屬性的機制,爲用戶提供訪問設備的接口。kobject的全部屬性,都在它對應的sysfs目錄下以文件的形式呈現。這些文件通常是可讀、可寫的,而kernel中定義了這些屬性的模塊,會根據用戶空間的讀寫操做,記錄和返回這些attribute的值。

所謂的屬性(attibute),就是內核空間和用戶空間進行信息交互的一種方法。例如某個driver定義了一個變量,卻但願用戶空間程序能夠修改該變量,以控制driver的運行行爲,那麼就能夠將該變量以sysfs attribute的形式開放出來。

3.2 attribute的建立

在linux內核中,attibute文件的建立是由fs/sysfs/file.c中sysfs_create_file接口完成的,該接口的實現大可能是文件系統相關的操做,和設備模型沒有太多的關係,此處先略過不提。

3.3 attribute的讀寫

全部的文件系統,都會定義一個struct file_operations變量,用於描述本文件系統的操做接口,sysfs也不例外:

 /* fs/sysfs/file.c, line 472 */
 const struct file_operations sysfs_file_operations = 
{
     .read    = sysfs_read_file,
     .write   = sysfs_write_file,
     .llseek  = generic_file_llseek,
     .open    = sysfs_open_file,
     .release = sysfs_release,
     .poll    = sysfs_poll,
};

 對attribute的讀寫,是經過sysfs的操做集(sysfs_file_operations)來進行的,實質是經過獲取屬性(kobject.ktype.attribute)對應的操做集(kobject.ktype.sysfs_ops)來對屬性進行操做。具體代碼分析以下:

static int sysfs_open_file(struct inode *inode, struct file *file)
{
    struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
    struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
    struct sysfs_buffer *buffer;
    const struct sysfs_ops *ops;

  //獲取kobj的屬性的操做集ops。若是該設備從屬的kobject沒有ktype,或者沒有ktype->sysfs_ops指針,是不容許它註冊任何attribute的
    if (kobj->ktype && kobj->ktype->sysfs_ops) 
        ops = kobj->ktype->sysfs_ops;
    else {
        WARN(1, KERN_ERR "missing sysfs attribute operations for "
               "kobject: %s\n", kobject_name(kobj));
        goto err_out;
    }

    buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
    if (!buffer)
        goto err_out;

    buffer->ops = ops;
    file->private_data = buffer; //將獲取的屬性操做集ops寫入struct file,隨後read、write接口即可取出來使用
  
  ............................
 }

attribute的操做集操做集(kobject.ktype.sysfs_ops)在內核中定義以下:

struct sysfs_ops 
{
    ssize_t    (*show)(struct kobject *, struct attribute *,char *);
    ssize_t    (*store)(struct kobject *,struct attribute *,const char *, size_t);
};

4. sysfs的應用示例

以Linux內核中的LED設備驅動框架爲例,對sysfs的應用進行總結。詳見:Linux字符設備驅動框架(二):Linux內核的LED設備驅動框架

相關文章
相關標籤/搜索