深入講解linux設(shè)備模型與sysfs
linux建立設(shè)備模型的目的:這事2.6內(nèi)核版本引入的一種設(shè)備管理機(jī)制,同時出現(xiàn)的還有sysfs文件系統(tǒng)(他完全表現(xiàn)向用戶呈現(xiàn)了內(nèi)核中設(shè)備的層次結(jié)構(gòu),也有人說之為設(shè)備模型的副產(chǎn)物),具體的為什么要引入設(shè)備模型呢?為內(nèi)核建立一個統(tǒng)一的設(shè)備模型,從而有一個對系統(tǒng)結(jié)構(gòu)的一般性抽象描述。好吧,這句話并不是很好懂。這樣說吧,跟以前比,引入他有什么好處呢?
1 電源管理,根據(jù)設(shè)備的層次關(guān)系,當(dāng)系統(tǒng)進(jìn)入睡眠的時候,不需要一個一個設(shè)備的關(guān),只需要關(guān)一個總線設(shè)備,接在總線下的設(shè)備就都會關(guān)掉。
2 sysfs 虛擬文件系統(tǒng)的實(shí)現(xiàn)與設(shè)備模型的緊密相關(guān), 并向外界展示它所表述的結(jié)構(gòu)。向用戶空間提供系統(tǒng)信息、改變操作參數(shù)的接口正越來越多地通過 sysfs , 也就是設(shè)備模型來完成。
3 關(guān)于熱插拔,這跟掃描有關(guān)系,比如說,你把一個設(shè)備直接接在USB上,系統(tǒng)就會去掃描設(shè)備,并且在USB總線上尋找匹配的設(shè)備驅(qū)動,最后初始化設(shè)備,等待用戶使用。
4 設(shè)備模型的實(shí)現(xiàn)需要創(chuàng)建一系列機(jī)制來處理對象的生命周期、對象間的關(guān)系和對象在用戶空間的表示。Linux 設(shè)備模型是一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。但對模型的大部分來說, Linux 設(shè)備模型代碼會處理好這些關(guān)系, 而不是把他們強(qiáng)加于驅(qū)動作者。模型隱藏于交互的背后,與設(shè)備模型的直接交互通常由總線級的邏輯和其他的內(nèi)核子系統(tǒng)處理。所以許多驅(qū)動作者可完全忽略設(shè)備模 型, 并相信設(shè)備模型能處理好他所負(fù)責(zé)的事。
怎么說呢,自從有了設(shè)備模型,我們需要寫的驅(qū)動代碼也少了,大多數(shù)面向用戶的接口都不需要實(shí)現(xiàn)了,只需要寫一些跟硬件相關(guān)的代碼。比如說input設(shè)備,上面的事件處理都是系統(tǒng)自帶的代碼,我們需要寫的只是從外設(shè)獲取輸入信息,然后提交給input core。在設(shè)備模型中,input就是class中的一個子目錄,其他的輸入設(shè)備(注冊在input中的)都只是他下面的文件。這些在sysfs文件系統(tǒng)中都可以看到。那就先來說說sysfs吧。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ?


sysfs文件系統(tǒng):用于將系統(tǒng)中的設(shè)備組織成層次結(jié)構(gòu),并向用戶模式程序提供詳細(xì)的內(nèi)核數(shù)據(jù)結(jié)構(gòu)信息。

這是sysfs下面的子目錄,設(shè)備模型可分為:驅(qū)動程序,設(shè)備,總線三部分。這些都會在這些目錄下體現(xiàn),這些目錄只是從不同的視角去看設(shè)備模型,比如說,block中只有塊設(shè)備,bus下既有驅(qū)動也有設(shè)備。class下也有設(shè)備信息,dev下是節(jié)點(diǎn),devices下是所有的設(shè)備等,都是交叉的。但他們都屬于設(shè)備模型三部分。
sysfs的信息來源是kobject層次結(jié)構(gòu),讀一個sysfs文件,就是動態(tài)的從kobject結(jié)構(gòu)提取信息,生成文件。這也解釋了設(shè)備模型與sysfs的關(guān)系。(kobject與kset就是構(gòu)成設(shè)備模型的關(guān)鍵結(jié)構(gòu)體)設(shè)備模型說到底還是一堆有序的結(jié)構(gòu)體構(gòu)成的。熱插拔的時候都會在對應(yīng)的地方產(chǎn)生新的結(jié)構(gòu)體(把一個結(jié)構(gòu)體插入到對應(yīng)的鏈表中去),或者刪除一個結(jié)構(gòu)體。
kobject 結(jié)構(gòu)為一些大的數(shù)據(jù)結(jié)構(gòu)和子系統(tǒng)提供了基本的對象管理,避免了類似機(jī)能的重復(fù)實(shí)現(xiàn)。這些機(jī)能包括
對象引用計(jì)數(shù).
維護(hù)對象鏈表(集合).
對象上鎖.
在用戶空間的表示.
每一個設(shè)備就是對應(yīng)一個kobject結(jié)構(gòu)體。在sysfs中對應(yīng)一個目錄。
相關(guān)函數(shù)
void kobject_init(struct kobject * kobj);kobject初始化函數(shù)。
int kobject_set_name(struct kobject *kobj, const char *format, ...);設(shè)置指定kobject的名稱。
struct kobject *kobject_get(struct kobject *kobj);將kobj 對象的引用計(jì)數(shù)加1,同時返回該對象的指針。
void kobject_put(struct kobject * kobj); 將kobj對象的引用計(jì)數(shù)減1,如果引用計(jì)數(shù)降為0,則調(diào)用kobject release()釋放該kobject對象。
int kobject_add(struct kobject * kobj);將kobj對象加入Linux設(shè)備層次。掛接該kobject對象到kset的list鏈中,增加父目錄各級kobject的引用計(jì)數(shù),在其 parent指向的目錄下創(chuàng)建文件節(jié)點(diǎn),并啟動該類型內(nèi)核對象的hotplug函數(shù)。
int kobject_register(struct kobject * kobj);kobject注冊函數(shù)。通過調(diào)用kobject init()初始化kobj,再調(diào)用kobject_add()完成該內(nèi)核對象的注冊。
void kobject_del(struct kobject * kobj);從Linux設(shè)備層次(hierarchy)中刪除kobj對象。
void kobject_unregister(struct kobject * kobj);kobject注銷函數(shù)。與kobject register()相反,它首先調(diào)用kobject del從設(shè)備層次中刪除該對象,再調(diào)用kobject put()減少該對象的引用計(jì)數(shù),如果引用計(jì)數(shù)降為0,則釋放kobject對象。

這個圖就表明了kset與kobject之中一部分指針之間的關(guān)系。這個圖大家都在用。
相關(guān)函數(shù) 系統(tǒng)在添加和刪除設(shè)備的時候都會用到這些函數(shù)來管理整個設(shè)備系統(tǒng)。 與kobject 相似,kset_init()完成指定kset的初始化,kset_get()和kset_put()分別增加和減少kset對象的引用計(jì)數(shù)。 Kset_add()和kset_del()函數(shù)分別實(shí)現(xiàn)將指定keset對象加入設(shè)備層次和從其中刪除;kset_register()函數(shù)完成 kset的注冊而kset_unregister()函數(shù)則完成kset的注銷。
kset中的subsystem:
如果說kset 是管理kobject 的集合,同理,subsystem 就是管理kset 的集合。它描述系統(tǒng)中某一類設(shè)備子系統(tǒng),如block subsys表示所有的塊設(shè)備,對應(yīng)于sysfs文件系統(tǒng)中的block目錄。類似的,devices subsys對應(yīng)于sysfs中的devices目錄,描述系統(tǒng)中所有的設(shè)備。Subsystem由struct subsystem數(shù)據(jù)結(jié)構(gòu)描述,
可以看出,subsystem與kset的區(qū)別就是多了一個信號量,所以在后來的代碼中,subsystem已經(jīng)完全被kset取締了。現(xiàn)在看到的應(yīng)該就是kset中有kset的情況。
想一想一個設(shè)備 一個驅(qū)動 一個總線,他們在系統(tǒng)中怎么描述呢?是結(jié)構(gòu)體。他們之間的關(guān)系怎么描述呢?是結(jié)構(gòu)體。怎么管理他們呢?啊 不是結(jié)構(gòu)體是函數(shù)啊。
