深入概述sysfs文件系統(tǒng),有這一篇就夠了!
內(nèi)核源碼:linux-2.6.38.8.tar.bz2
目標(biāo)平臺(tái):ARM體系結(jié)構(gòu)
sysfs是基于內(nèi)存的文件系統(tǒng),用于向用戶(hù)空間導(dǎo)出內(nèi)核對(duì)象并且能對(duì)其進(jìn)行讀寫(xiě)。
1、sysfs文件系統(tǒng)不支持特殊文件,只支持目錄、普通文件(文本或二進(jìn)制文件)和符號(hào)鏈接文件等三種類(lèi)型,在內(nèi)核中都使用struct sysfs_dirent結(jié)構(gòu)體來(lái)表示,相當(dāng)于其他文件系統(tǒng)在硬盤(pán)或flash里的數(shù)據(jù)。源代碼如下所示:
struct sysfs_dirent分為四種類(lèi)型,如下所示:
struct sysfs_open_dirent等結(jié)構(gòu)體的詳細(xì)信息后文說(shuō)明。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??


2、sysfs文件系統(tǒng)的初始化是由sysfs_init函數(shù)來(lái)完成的(該函數(shù)由vfs_caches_init函數(shù)所調(diào)用的mnt_init函數(shù)調(diào)用),執(zhí)行文件系統(tǒng)的注冊(cè)和掛載,與rootfs根文件系統(tǒng)的相關(guān)操作類(lèi)似。源代碼如下所示:
在用戶(hù)空間一般都將sysfs文件系統(tǒng)掛載在/sys目錄,而這里也有一次通過(guò)kern_mount函數(shù)的掛載,這樣的話 sysfs文件系統(tǒng)就會(huì)掛載兩次?其實(shí)是沒(méi)有的,后者的掛載并沒(méi)有將當(dāng)前的struct vfsmount結(jié)構(gòu)體實(shí)例插入到掛載樹(shù)中,而是保存在全局指針sysfs_mnt中,并且會(huì)與用戶(hù)空間掛載sysfs文件系統(tǒng)時(shí)所創(chuàng)建的struct vfsmount結(jié)構(gòu)體實(shí)例共享相同的超級(jí)塊。因此,無(wú)論用戶(hù)空間的掛載操作是否執(zhí)行,sysfs文件系統(tǒng)都會(huì)存在于內(nèi)核之中(編譯內(nèi)核有配置CONFIG_SYSFS選項(xiàng))。sysfs文件系統(tǒng)的struct file_system_type結(jié)構(gòu)體實(shí)例如下所示:
其中,sysfs_test_super函數(shù)用于判斷struct sysfs_super_info結(jié)構(gòu)體數(shù)據(jù)是否相同以便確認(rèn)是否可以共享超級(jí)塊,源代碼如下所示:
sysfs_fill_super函數(shù)主要用于創(chuàng)建sysfs文件系統(tǒng)根目錄所對(duì)應(yīng)的目錄項(xiàng)及其i節(jié)點(diǎn),并且將sysfs_root作為根目錄項(xiàng)的私有數(shù)據(jù)。源代碼如下所示:
3、文件系統(tǒng)最核心的內(nèi)容是要看其i節(jié)點(diǎn)是如何構(gòu)建的,sysfs文件系統(tǒng)使用sysfs_init_inode函數(shù)來(lái)創(chuàng)建。源代碼如下所示:
四種structsysfs_dirent類(lèi)型對(duì)應(yīng)三種文件類(lèi)型,其中SYSFS_KOBJ_ATTR和SYSFS_KOBJ_BIN_ATTR都為普通文件。文件系統(tǒng)針對(duì)不同的文件類(lèi)型,i節(jié)點(diǎn)操作函數(shù)(struct inode_operations)和文件內(nèi)容操作函數(shù)(struct file_operations)都會(huì)有不同的實(shí)現(xiàn),并且其中的函數(shù)也是根據(jù)文件類(lèi)型來(lái)決定是否實(shí)現(xiàn)(大部分成員為空指針)。
3.1、目錄的i節(jié)點(diǎn)操作函數(shù)和文件內(nèi)容操作函數(shù)分別為sysfs_dir_inode_operations和sysfs_dir_operations,其中i節(jié)點(diǎn)操作函數(shù)的create、mkdir和rmdir等成員都為空指針,表示sysfs文件系統(tǒng)的目錄或文件無(wú)法從用戶(hù)空間通過(guò)系統(tǒng)調(diào)用來(lái)創(chuàng)建和刪除。對(duì)于sysfs文件系統(tǒng)中的目錄來(lái)說(shuō),i節(jié)點(diǎn)操作函數(shù)最重要的是查找函數(shù)sysfs_lookup,文件內(nèi)容操作函數(shù)最重要的是遍歷目錄函數(shù)sysfs_readdir。源代碼如下所示:
對(duì)于目錄來(lái)說(shuō),只能有一個(gè)目錄項(xiàng)別名。
當(dāng)在用戶(hù)空間通過(guò)ls等命令查看sysfs文件系統(tǒng)的目錄時(shí),會(huì)通過(guò)系統(tǒng)調(diào)用getdents調(diào)用vfs_readdir,然后再調(diào)用sysfs_readdir函數(shù)。其中參數(shù)filp表示該目錄打開(kāi)之后的文件指針,dirent實(shí)際為struct getdents_callback類(lèi)型的數(shù)據(jù),filldir為回調(diào)函數(shù)指針,指向同名的filldir函數(shù)。源代碼如下所示:
3.2、sysfs文件系統(tǒng)針對(duì)文本文件和二進(jìn)制文件實(shí)現(xiàn)了不同的文件內(nèi)容操作函數(shù),而i節(jié)點(diǎn)操作函數(shù)則相同。源代碼如下所示:
針對(duì)普通文件,最重要的是觀察它的文件內(nèi)容操作函數(shù)的實(shí)現(xiàn),如open、read和write等函數(shù)。下面則以文本文件為例,看看sysfs文件系統(tǒng)是如何讀寫(xiě)文件的。源代碼如下所示:
在sysfs文件系統(tǒng)中,文本文件使用struct sysfs_elem_attr來(lái)表示,而該結(jié)構(gòu)體有一個(gè)struct sysfs_open_dirent類(lèi)型的open成員,主要用于管理每次打開(kāi)并讀/寫(xiě)該文件時(shí)所使用的內(nèi)存(struct sysfs_buffer)。源代碼如下所示:
sysfs_read_file為sysfs文件系統(tǒng)文本文件的讀函數(shù),源代碼如下所示:
sysfs_write_file為sysfs文件系統(tǒng)的寫(xiě)函數(shù),源代碼如下所示:
關(guān)閉文件時(shí),打開(kāi)、讀/寫(xiě)文件時(shí)所分配的內(nèi)存都會(huì)釋放,并不會(huì)一直存在于內(nèi)核中。
3.3、對(duì)于符號(hào)鏈接文件來(lái)說(shuō),它沒(méi)有文件內(nèi)容操作函數(shù),只有i節(jié)點(diǎn)操作函數(shù),其中最重要的函數(shù)為符號(hào)鏈接文件的解析函數(shù)sysfs_follow_link,源代碼如下所示:
讀取符號(hào)鏈接文件內(nèi)容的函數(shù)generic_readlink主要就是靠解析函數(shù)來(lái)實(shí)現(xiàn)的,源代碼如下所示:
其中,sysfs_put_link函數(shù)執(zhí)行與sysfs_follow_link函數(shù)相反的操作,這里只是釋放由sysfs_follow_link函數(shù)分配的內(nèi)存。
4、對(duì)于sysfs文件系統(tǒng)來(lái)說(shuō),在用戶(hù)空間只能讀寫(xiě)文件的內(nèi)容,而無(wú)法創(chuàng)建或刪除文件或目錄,只能在內(nèi)核中通過(guò)sysfs_create_dir、sysfs_create_file等等函數(shù)來(lái)實(shí)現(xiàn)。
4.1、內(nèi)核對(duì)象(struct kobject)對(duì)應(yīng)于sysfs文件系統(tǒng)中的目錄,可使用sysfs_create_dir函數(shù)來(lái)創(chuàng)建,源代碼如下所示:
4.2、內(nèi)核對(duì)象的屬性(struct attribute)對(duì)應(yīng)于sysfs文件系統(tǒng)中的文本文件,可使用sysfs_create_file函數(shù)來(lái)創(chuàng)建,源代碼如下所示:
sysfs文件系統(tǒng)中的二進(jìn)制文件通過(guò)sysfs_create_bin_file函數(shù)來(lái)創(chuàng)建,符號(hào)鏈接文件通過(guò)sysfs_create_link函數(shù)來(lái)創(chuàng)建。
