




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、52/52HYPERLINK /bailyzheng/article/details/8043500 Linux設(shè)備驅(qū)動(dòng)編程模型之上層容器篇 分類: HYPERLINK /bailyzheng/article/category/1125013 Linux 2012-10-06 17:18 245人閱讀 HYPERLINK /bailyzheng/article/details/8043500 l comments 評(píng)論(0) HYPERLINK javascript:void(0); o 收藏 收藏 HYPERLINK /bailyzheng/article/details/8043500 l
2、 report o 舉報(bào) 舉報(bào) HYPERLINK /tag/linux t _blank linux HYPERLINK /tag/%e7%bc%96%e7%a8%8b t _blank 編程 HYPERLINK /tag/struct t _blank struct HYPERLINK /tag/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84 t _blank 數(shù)據(jù)結(jié)構(gòu) HYPERLINK /tag/list t _blank list HYPERLINK /tag/null t _blank null2.6內(nèi)核增加了一個(gè)引人注目的新特性統(tǒng)一設(shè)備模型(device
3、model)。設(shè)備模型提供了一個(gè)獨(dú)立的機(jī)制專門(mén)來(lái)表示設(shè)備,并描述其在系統(tǒng)中的拓?fù)浣Y(jié)構(gòu),從而使得系統(tǒng)具有以下優(yōu)點(diǎn):代碼重復(fù)最小化。提供諸如引用計(jì)數(shù)這樣的統(tǒng)一機(jī)制??梢粤信e系統(tǒng)中所有的設(shè)備,觀察它們的狀態(tài),并且查看它們連接的總線??梢詫⑾到y(tǒng)中的全部設(shè)備結(jié)構(gòu)以樹(shù)的形式完整、有效的展現(xiàn)出來(lái)包括所有的總線和內(nèi)部連接??梢詫⒃O(shè)備和其對(duì)應(yīng)的驅(qū)動(dòng)聯(lián)系起來(lái),反之亦然。可以將設(shè)備按照類型加以歸類,比如分類為輸入設(shè)備,而無(wú)需理解物理設(shè)備的拓?fù)浣Y(jié)構(gòu)。可以沿設(shè)備樹(shù)的葉子向其根的方向依次遍歷,以保證能以正確順序關(guān)閉各設(shè)備的電源。最后一點(diǎn)是實(shí)現(xiàn)設(shè)備模型的最初動(dòng)機(jī)。若想在內(nèi)核中實(shí)現(xiàn)智能的電源管理,就需要來(lái)建立表示系統(tǒng)中設(shè)備拓
4、撲關(guān)系的樹(shù)結(jié)構(gòu)。當(dāng)在樹(shù)上端的設(shè)備關(guān)閉電源時(shí),內(nèi)核必須首先關(guān)閉該設(shè)備節(jié)點(diǎn)以下的(處于葉子上的)設(shè)備電源。比如內(nèi)核需要先關(guān)閉一個(gè)USB鼠標(biāo),然后才可關(guān)閉USB控制器;同樣內(nèi)核也必須在關(guān)閉PCI總線前先關(guān)閉USB控制器。簡(jiǎn)而言之,若要準(zhǔn)確而又高效的完成上述電源管理目標(biāo),內(nèi)核無(wú)疑需要一顆設(shè)備樹(shù)。一、原理雖然設(shè)備模型的初衷是為了方便電源管理而提供出的一種設(shè)備拓?fù)浣Y(jié)構(gòu),但是,為了方便調(diào)試,設(shè)備模型的開(kāi)發(fā)者決定將設(shè)備結(jié)構(gòu)樹(shù)導(dǎo)出為一個(gè)文件系統(tǒng),這就是sysfs文件系統(tǒng),它可以幫助用戶能以一個(gè)簡(jiǎn)單文件系統(tǒng)的方式來(lái)觀察系統(tǒng)中各種設(shè)備的拓?fù)浣Y(jié)構(gòu)。這個(gè)舉措很快被證明是非常明智的,首先sysfs代替了先前處于/proc
5、下的設(shè)備相關(guān)文件;另外它為系統(tǒng)對(duì)象提供了一個(gè)很有效的視圖。實(shí)際上,sysfs起初被稱為driverfs。最終sysfs使得我們認(rèn)識(shí)到一個(gè)全新的對(duì)象模型非常有利于系統(tǒng)。今天所有2.6內(nèi)核的系統(tǒng)都擁有sysfs文件系統(tǒng),而且?guī)缀醵己翢o(wú)例外的將其掛載。圖一是掛載于/sys目錄下的sysfs文件系統(tǒng)的局部視圖。/sys|block/|fd0|hda|dev|device-././devices/pci0000:00/0000:00:1f.1/ide0/0.0|bus/|class/|devices/|firmware/|power/|module/Sysfs的根目錄下包含了七個(gè)目錄:block,bus
6、,class,devices,firmware,module和power。block目錄下的每個(gè)子目錄都對(duì)應(yīng)著系統(tǒng)中的一個(gè)塊設(shè)備。反過(guò)來(lái),每個(gè)目錄下又都包含了該塊設(shè)備的所有分區(qū)。bus目錄提供了一個(gè)系統(tǒng)總線視圖。class目錄包含了以高層功能邏輯組織起來(lái)的系統(tǒng)設(shè)備視圖。devices目錄是系統(tǒng)中設(shè)備拓?fù)浣Y(jié)構(gòu)視圖,它直接映射出了內(nèi)核中設(shè)備結(jié)構(gòu)體的組織層次。firmware目錄包含了一些諸如ACPI,EDD,EFI等低層子系統(tǒng)的特殊樹(shù)。power目錄包含了系統(tǒng)范圍的電源管理數(shù)據(jù)。其中最重要的目錄是devices,該目錄將設(shè)備模型導(dǎo)出到用戶空間。目錄結(jié)構(gòu)就是系統(tǒng)中實(shí)際的設(shè)備拓?fù)?。其它目錄中的很多?shù)據(jù)
7、都是將devices目錄下的數(shù)據(jù)加以轉(zhuǎn)換加工而得。比如,/sys/class/net/目錄是以注冊(cè)網(wǎng)絡(luò)接口這一高層概念來(lái)組織設(shè)備關(guān)系的,在這個(gè)目中可能會(huì)有目錄eth0,它里面包含的devices文件其實(shí)就是一個(gè)指回到devices下實(shí)際設(shè)備目錄的符號(hào)連接。隨便看看任何你可訪問(wèn)到的Linux系統(tǒng),這種系統(tǒng)設(shè)備視圖相當(dāng)準(zhǔn)確和漂亮,而且可以看到class中的高層概念與devices中的低層物理設(shè)備,以及bus中的實(shí)際驅(qū)動(dòng)程序之間互相聯(lián)絡(luò)是非常廣泛的。Sysfs文件系統(tǒng)的目標(biāo)就是要展現(xiàn)設(shè)備驅(qū)動(dòng)模型組件之間的層次關(guān)系。在Linux中,sysfs文件系統(tǒng)被安裝于/sys目錄下:mount-tsysfssy
8、sfs/sys/sys|block/|fd0|hda|dev|device-././devices/pci0000:00/0000:00:1f.1/ide0/0.0|bus/|class/|devices/|firmware/|power/|module/那么,在這樣的目錄樹(shù)中,哪些目錄是驅(qū)動(dòng)模型要關(guān)注的對(duì)象?bus-系統(tǒng)中用于連接設(shè)備的總線,在內(nèi)核中對(duì)應(yīng)的結(jié)構(gòu)體為structbus_type;device-內(nèi)核所識(shí)別的所有設(shè)備,依照連接它們的總線對(duì)其進(jìn)行組織,對(duì)應(yīng)的結(jié)構(gòu)體為structdevice;class-系統(tǒng)中設(shè)備的類型(聲卡,網(wǎng)卡,顯卡,輸入設(shè)備等),同一類中包含的設(shè)備可能連接到不同
9、的總線,對(duì)應(yīng)的結(jié)構(gòu)體為structclass;為什么不對(duì)Power進(jìn)行單獨(dú)描述?實(shí)際上,Power與device有關(guān),它只是device中的一個(gè)字段。除此之外,立馬閃現(xiàn)在我們腦子里的對(duì)象還有:driver-在內(nèi)核中注冊(cè)的設(shè)備驅(qū)動(dòng)程序,對(duì)應(yīng)的結(jié)構(gòu)體為structdevice_driver;以上bus,device,class,driver,是可以感受到的對(duì)象,在內(nèi)核中都用相應(yīng)的結(jié)構(gòu)體來(lái)描述。而實(shí)際上,按照面向?qū)ο蟮乃枷?,我們需要抽象出一個(gè)最基本的對(duì)象,這就是設(shè)備模型的核心對(duì)象kobject.Kobject是Linux2.6引入的新的設(shè)備管理機(jī)制,在內(nèi)核中就是一個(gè)structkobject結(jié)構(gòu)體。
10、有了這個(gè)數(shù)據(jù)結(jié)構(gòu),內(nèi)核中所有設(shè)備在底層都具有統(tǒng)一的接口,kobject提供基本的對(duì)象管理,是構(gòu)成Linux2.6設(shè)備模型的核心結(jié)構(gòu),它與sysfs文件系統(tǒng)緊密關(guān)聯(lián),每個(gè)在內(nèi)核中注冊(cè)的kobject對(duì)象都對(duì)應(yīng)于sysfs文件系統(tǒng)中的一個(gè)目錄。Kobject是組成設(shè)備模型的基本結(jié)構(gòu)。類似于C+中的基類,它嵌入于更大的對(duì)象中,即所謂的容器,如上面提到的bus,class,devices,drivers都是典型的容器,它們是描述設(shè)備模型的組件。二、主要對(duì)象介紹1,核心對(duì)象kobject話說(shuō)kobject是驅(qū)動(dòng)模型的核心對(duì)象,但在sysfs文件系統(tǒng)中似乎并沒(méi)有對(duì)應(yīng)的項(xiàng),而這種看似“無(wú)”,實(shí)際上蘊(yùn)藏著“有
11、”。這“有”從何說(shuō)起?;叵胛募到y(tǒng)中的核心對(duì)象“索引節(jié)點(diǎn)(indoe)”和目錄項(xiàng)“dentry”:Inode與文件系統(tǒng)中的一個(gè)文件相對(duì)應(yīng)(而實(shí)際上,只有文件被訪問(wèn)時(shí),才在內(nèi)存創(chuàng)建索引節(jié)點(diǎn))。Dentry-每個(gè)路徑中的一個(gè)分量,例如路徑/bin/ls,其中/、bin和ls三個(gè)都是目錄項(xiàng),只是前兩個(gè)是目錄,而最后一個(gè)是普通文件。也就是說(shuō),目錄項(xiàng)目錄項(xiàng)或者是一子目錄,或者是一個(gè)文件。從上面的定義可以看出,indoe和dentry誰(shuí)的包容性更大?當(dāng)然是dentry!那么,kobject與dentry有何關(guān)系?由此我們可以推想,把dentry作為kobject中的一個(gè)字段,恍然間,kobject變得強(qiáng)大
12、起來(lái)了。何謂“強(qiáng)大“,因?yàn)檫@樣以來(lái),就可以方便地將kobject映射到一個(gè)dentry上,也就是說(shuō),kobject與/sys下的任何一個(gè)目錄或文件相對(duì)應(yīng)了,進(jìn)一步說(shuō),把kobject導(dǎo)出形成文件系統(tǒng)就變得如同在內(nèi)存中構(gòu)建目錄項(xiàng)一樣簡(jiǎn)單。由此可知,kobject其實(shí)已經(jīng)形成一棵樹(shù)了。這就是以隱藏在背后的對(duì)象模型為橋梁,將驅(qū)動(dòng)模型和sysfs文件系統(tǒng)全然聯(lián)系起來(lái)。由于kobject被映射到目錄項(xiàng),同時(shí)對(duì)象模型層次結(jié)構(gòu)也已經(jīng)在內(nèi)存形成一個(gè)樹(shù),因此sysfs的形成就水到渠成了。既然,kobject要形成一顆樹(shù),那么其中的字段就要有parent,以表示樹(shù)的層次關(guān)系;另外,kobject不能是無(wú)名氏,得有
13、name字段,按說(shuō),目錄或文件名并不會(huì)很長(zhǎng),但是,sysfs文件系統(tǒng)為了表示對(duì)象之間復(fù)雜的關(guān)系,需要通過(guò)軟鏈接達(dá)到,而軟鏈接常常有較長(zhǎng)的名字。cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ?
14、 ?/*設(shè)備驅(qū)動(dòng)程序模型的核心數(shù)據(jù)結(jié)構(gòu),每個(gè)kobject數(shù)據(jù)結(jié)構(gòu)對(duì)應(yīng)于sysfs文件系統(tǒng)中的一個(gè)目錄*/structkobjectconstchar*name;/*指向含有容器名稱的字符*/structlist_headentry;/*用于kobject所插入的鏈表的指針*/structkobject*parent;/*指向父kobject*/structkset*kset;/*指向包含的kset*/structkobj_type*ktype;/*指向kobject的類型的描述符*/structsysfs_dirent*sd;/*用同一種structsysfs_dirent來(lái)統(tǒng)一設(shè)備模型中的
15、kset/kobject/attr/attr_group.*/structkrefkref;/*容器的引用計(jì)數(shù)器*/unsignedintstate_initialized:1;/*指明kobject是否被初始化*/unsignedintstate_in_sysfs:1;/*指明是否使用了sysfs*/unsignedintstate_add_uevent_sent:1;/*熱插拔加載事件*/unsignedintstate_remove_uevent_sent:1;/*熱插拔卸載事件*/unsignedintuevent_suppress:1;/*如果設(shè)置了uevent_suppress字段
16、,說(shuō)明不希望產(chǎn)生事件,忽略事件正確返回*/;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?/*設(shè)備驅(qū)動(dòng)程序模型的核心數(shù)據(jù)結(jié)構(gòu),每個(gè)kobject數(shù)據(jù)結(jié)構(gòu)對(duì)應(yīng)于s
17、ysfs文件系統(tǒng)中的一個(gè)目錄*/structkobjectconstchar*name;/*指向含有容器名稱的字符*/structlist_headentry;/*用于kobject所插入的鏈表的指針*/structkobject*parent;/*指向父kobject*/structkset*kset;/*指向包含的kset*/structkobj_type*ktype;/*指向kobject的類型的描述符*/structsysfs_dirent*sd;/*用同一種structsysfs_dirent來(lái)統(tǒng)一設(shè)備模型中的kset/kobject/attr/attr_group.*/struct
18、krefkref;/*容器的引用計(jì)數(shù)器*/unsignedintstate_initialized:1;/*指明kobject是否被初始化*/unsignedintstate_in_sysfs:1;/*指明是否使用了sysfs*/unsignedintstate_add_uevent_sent:1;/*熱插拔加載事件*/unsignedintstate_remove_uevent_sent:1;/*熱插拔卸載事件*/unsignedintuevent_suppress:1;/*如果設(shè)置了uevent_suppress字段,說(shuō)明不希望產(chǎn)生事件,忽略事件正確返回*/;2.引用計(jì)數(shù)krefkobje
19、ct的主要功能之一就是為我們提供了一個(gè)統(tǒng)一的引用計(jì)數(shù)系統(tǒng),為什么說(shuō)它具有“統(tǒng)一”的能力?那是因?yàn)閗object是“基”對(duì)象,就像大廈的基地,其他對(duì)象(如devic,bus,class,device_driver等容器)都將其包含,以后,其他對(duì)象的引用技術(shù)繼承或封裝kobject的引用技術(shù)就可以了。初始化時(shí),kobject的引用計(jì)數(shù)設(shè)置為1。只要引用計(jì)數(shù)不為零,那么該對(duì)象就會(huì)繼續(xù)保留在內(nèi)存中,也可以說(shuō)是被“釘住”了。任何包含對(duì)象引用的代碼首先要增加該對(duì)象的引用計(jì)數(shù),當(dāng)代碼結(jié)束后則減少它的引用計(jì)數(shù)。增加引用計(jì)數(shù)稱為獲得(getting)對(duì)象的引用,減少引用計(jì)數(shù)稱為釋放(putting)對(duì)象的引用。
20、當(dāng)引用計(jì)數(shù)跌到零時(shí),對(duì)象便可以被銷毀,同時(shí)相關(guān)內(nèi)存也都被釋放。增加一個(gè)引用計(jì)數(shù)可通過(guò)koject_get()函數(shù)完成:structkobject*kobject_get(structkobject*kobj);該函數(shù)正常情況下將返回一個(gè)指向kobject的指針,如果失敗則返回NULL指針;減少引用計(jì)數(shù)通過(guò)kobject_put()完成:voidkobject_put(structkobject*kobj);如果對(duì)應(yīng)的kobject的引用計(jì)數(shù)減少到零,則與該kobject關(guān)聯(lián)的ktype中的析構(gòu)函數(shù)將被調(diào)用。我們深入到引用計(jì)數(shù)系統(tǒng)的內(nèi)部去看,會(huì)發(fā)現(xiàn)kobject的引用計(jì)數(shù)是通過(guò)kref結(jié)構(gòu)體實(shí)現(xiàn)
21、的,該結(jié)構(gòu)體定義在頭文件中:structkrefatomic_trefcount;其中唯一的字段是用來(lái)存放引用計(jì)數(shù)的原子變量。那為什么采用結(jié)構(gòu)體?這是為了便于進(jìn)行類型檢測(cè)。在使用kref前,必須先通過(guò)kref_init()函數(shù)來(lái)初始化它:void kref_init(struct kref *kref) atomic_set(&kref-refcount, 1);正如你所看到的,這個(gè)函數(shù)簡(jiǎn)單的將原子變量置1,所以kref一但被初始化,它表示的引用計(jì)數(shù)便固定為1。開(kāi)發(fā)者現(xiàn)在不必在內(nèi)核代碼中利用atmoic_t類型來(lái)實(shí)現(xiàn)其自己的引用計(jì)數(shù)。對(duì)開(kāi)發(fā)者而言,在內(nèi)核代碼中最好的方法是利用kref類型和它相
22、應(yīng)的輔助函數(shù),為自己提供一個(gè)通用的、正確的引用計(jì)數(shù)機(jī)制。上述的所有函數(shù)定義與聲明分別在在文件lib/kref.c和文件中。3.共同特性的ktype如上所述,kobject是一個(gè)抽象而基本的對(duì)象。對(duì)于一族具有共同特性的kobject,就是用ktype來(lái)描述:cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o p
23、rint print HYPERLINK /bullbat/article/details/7259261 o ? ?structkobj_typevoid(*release)(structkobject*kobj);structsysfs_ops*sysfs_ops;structattribute*default_attrs;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYP
24、ERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?structkobj_typevoid(*release)(structkobject*kobj);structsysfs_ops*sysfs_ops;structattribute*default_attrs;定義于頭文件中。release指針指向在kobject引用計(jì)數(shù)減至零時(shí)要被調(diào)用的析構(gòu)函數(shù)。該函數(shù)負(fù)責(zé)釋放所有kobject使用的內(nèi)存和其它相關(guān)清理工作。sysfs_ops變
25、量指向sysfs_ops結(jié)構(gòu)體,其中包含兩個(gè)函數(shù),也就是對(duì)屬性進(jìn)行操作的讀寫(xiě)函數(shù)show()和store()。最后,default_attrs指向一個(gè)attribute結(jié)構(gòu)體數(shù)組。這些結(jié)構(gòu)體定義了kobject相關(guān)的默認(rèn)屬性。屬性描述了給定對(duì)象的特征,其實(shí),屬性就是對(duì)應(yīng)/sys樹(shù)形結(jié)構(gòu)中的葉子結(jié)點(diǎn),也就是文件。4.對(duì)象集合體ksetKset,顧名思義就是kobject對(duì)象的集合體,可以把它看成是一個(gè)容器,可將所有相關(guān)的kobject對(duì)象聚集起來(lái),比如“全部的塊設(shè)備”就是一個(gè)kset。聽(tīng)起來(lái)kset與ktypes非常類似,好像沒(méi)有多少實(shí)質(zhì)內(nèi)容。那么“為什么會(huì)需要這兩個(gè)類似的東西呢”。ksets可
26、把kobject集中到一個(gè)集合中,而ktype描述相關(guān)類型kobject所共有的特性,它們之間的重要區(qū)別在于:具有相同ktype的kobject可以被分組到不同的ksets。kobject的kset指針指向相應(yīng)的kset集合。kset集合由kset結(jié)構(gòu)體表示,定義于頭文件中:cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7
27、259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?structksetstructlist_headlist;/*包含在kset中的kobject類型的描述符*/spinlock_tlist_lock;/*嵌入的kobject結(jié)構(gòu),位于kset中的kobject,其parent字段指向這個(gè)內(nèi)嵌的kobject指針*/structkobjectkobj;/*指向用于處理kobject結(jié)構(gòu)的過(guò)濾和熱插拔操作的回調(diào)函數(shù)表*/structkset_uevent_ops*uevent_ops;cpp HYPERLIN
28、K /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?structksetstructlist_headlist;/*包含在kset中的kobject類型的描述符*/spinlock_tlis
29、t_lock;/*嵌入的kobject結(jié)構(gòu),位于kset中的kobject,其parent字段指向這個(gè)內(nèi)嵌的kobject指針*/structkobjectkobj;/*指向用于處理kobject結(jié)構(gòu)的過(guò)濾和熱插拔操作的回調(diào)函數(shù)表*/structkset_uevent_ops*uevent_ops;其中ktype指針指向集合(kset)中kobject對(duì)象的類型(ktype),list連接該集合(kset)中所有的kobject對(duì)象。kobj指向的koject對(duì)象代表了該集合的基類, HYPERLINK http:/lxr.linux.no/linux/+code=uevent_ops uev
30、ent_ops指向一個(gè)用于處理集合中kobject對(duì)象的熱插拔操作的結(jié)構(gòu)體。5,sys文件系統(tǒng)目錄實(shí)體sysfs_direntsysfs文件系統(tǒng)有自己的dirent結(jié)構(gòu),dirent=directoryentry(目錄實(shí)體)。sysfs中,每一個(gè)dentry對(duì)應(yīng)了一個(gè)dirent結(jié)構(gòu),dentry-d_fsdata是一個(gè)void的指針,它指向sysfs_dirent結(jié)構(gòu)。每個(gè)kobject結(jié)構(gòu)對(duì)應(yīng)一個(gè)dirent結(jié)構(gòu)。每個(gè)文件(包括目錄文件)都對(duì)應(yīng)一個(gè)sysfs_dirent對(duì)象,在建立目錄和文件后,內(nèi)存中會(huì)形成一棵以sysfs_root為根的目錄樹(shù)結(jié)構(gòu)。屬性attribute結(jié)構(gòu)對(duì)應(yīng)sysf
31、s中的文件,也用sysfs_dirent結(jié)構(gòu)表示。這樣sysfs_dirent的組織就是sysfs的樹(shù)形結(jié)構(gòu)的映射。cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?/*structsys
32、fs_dirent就是用來(lái)做kobject與dentry的互相轉(zhuǎn)換用的*/structsysfs_direntatomic_ts_count;atomic_ts_active;structsysfs_dirent*s_parent;structsysfs_dirent*s_sibling;constchar*s_name;/*共用體包含四種不同的結(jié)構(gòu),分別是目錄、符號(hào)鏈接文件、屬性文件、二進(jìn)制屬性文件其中目錄類型可以對(duì)應(yīng)kobject,在相應(yīng)的s_dir中也有對(duì)kobject的指針,因此在內(nèi)核數(shù)據(jù)結(jié)構(gòu),kobject與sysfs_dirent是互相引用的;*/unionstructsysfs_
33、elem_dirs_dir;structsysfs_elem_symlinks_symlink;structsysfs_elem_attrs_attr;structsysfs_elem_bin_attrs_bin_attr;unsignedints_flags;ino_ts_ino;umode_ts_mode;structsysfs_inode_attrs*s_iattr;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/
34、8043500 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?/*structsysfs_dirent就是用來(lái)做kobject與dentry的互相轉(zhuǎn)換用的*/structsysfs_direntatomic_ts_count;atomic_ts_active;structsysfs_dirent*s_parent;structsysfs_dirent*s_sibling;constchar*s_n
35、ame;/*共用體包含四種不同的結(jié)構(gòu),分別是目錄、符號(hào)鏈接文件、屬性文件、二進(jìn)制屬性文件其中目錄類型可以對(duì)應(yīng)kobject,在相應(yīng)的s_dir中也有對(duì)kobject的指針,因此在內(nèi)核數(shù)據(jù)結(jié)構(gòu),kobject與sysfs_dirent是互相引用的;*/unionstructsysfs_elem_dirs_dir;structsysfs_elem_symlinks_symlink;structsysfs_elem_attrs_attr;structsysfs_elem_bin_attrs_bin_attr;unsignedints_flags;ino_ts_ino;umode_ts_mode;st
36、ructsysfs_inode_attrs*s_iattr;下面是設(shè)備驅(qū)動(dòng)模型核心數(shù)據(jù)結(jié)構(gòu)關(guān)系圖總結(jié):kobject通常是嵌入到其它結(jié)構(gòu)中的,其單獨(dú)意義其實(shí)并不大。相反,那些更為重要的結(jié)構(gòu)體,比如在structcdev中才真正需要用到kobject結(jié)構(gòu)。cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o pr
37、int print HYPERLINK /bullbat/article/details/7259261 o ? ?structcdevstructkobjectkobj;structmodule*owner;conststructfile_operations*ops;structlist_headlist;dev_tdev;unsignedintcount;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/804350
38、0 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?structcdevstructkobjectkobj;structmodule*owner;conststructfile_operations*ops;structlist_headlist;dev_tdev;unsignedintcount;當(dāng)kobject被嵌入到其它結(jié)構(gòu)中時(shí),該結(jié)構(gòu)便擁有了kobject提供的標(biāo)準(zhǔn)功能。更重要的一點(diǎn)是,嵌入
39、kobject的結(jié)構(gòu)體可以成為對(duì)象層次架構(gòu)中的一部分。比如cdev結(jié)構(gòu)體就可通過(guò)其父指針cdev-kobj-parent和鏈表cdev-kobj-entry來(lái)插入到對(duì)象層次結(jié)構(gòu)中三、主要方法對(duì)設(shè)備驅(qū)動(dòng)模型中核心的數(shù)據(jù)結(jié)構(gòu)做了總結(jié),對(duì)他們的操作就不難理解了,可以猜得到都是根據(jù)上面關(guān)系圖來(lái)實(shí)現(xiàn)的方法。對(duì)每個(gè)數(shù)據(jù)結(jié)構(gòu)都有很多實(shí)現(xiàn)的函數(shù),這里我們只分析一個(gè),即kset的注冊(cè)。這個(gè)函數(shù)的實(shí)現(xiàn)涉及到了上面的所有數(shù)據(jù)結(jié)構(gòu)。我也是根據(jù)這個(gè)函數(shù)畫(huà)出上面的關(guān)系圖的。kset注冊(cè)cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plai
40、n HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?/*kset_register-initializeandaddakset.*k:kset.*/intkset_register(structkset*k)interr;if(!k)return-EINVAL;/*基本的初始化*/kset_init(k);/*kobj以及其屬
41、性建立sd樹(shù)*/err=kobject_add_internal(&k-kobj);if(err)returnerr;/*事件相關(guān)*/kobject_uevent(&k-kobj,KOBJ_ADD);return0;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print
42、HYPERLINK /bailyzheng/article/details/8043500 o ? ?/*kset_register-initializeandaddakset.*k:kset.*/intkset_register(structkset*k)interr;if(!k)return-EINVAL;/*基本的初始化*/kset_init(k);/*kobj以及其屬性建立sd樹(shù)*/err=kobject_add_internal(&k-kobj);if(err)returnerr;/*事件相關(guān)*/kobject_uevent(&k-kobj,KOBJ_ADD);return0;kse
43、t初始化cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?/*kset_init-initializeaksetforuse*k:kset*/voidkset_init(structkse
44、t*k)/*kobject結(jié)構(gòu)初始化*/kobject_init_internal(&k-kobj);/*初始化kset的kobject鏈表*/INIT_LIST_HEAD(&k-list);spin_lock_init(&k-list_lock);cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/article/details/80435
45、00 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?/*kset_init-initializeaksetforuse*k:kset*/voidkset_init(structkset*k)/*kobject結(jié)構(gòu)初始化*/kobject_init_internal(&k-kobj);/*初始化kset的kobject鏈表*/INIT_LIST_HEAD(&k-list);spin_lock_init(&k-list_lock);cpp HYPERLINK /bullbat/article/details/725
46、9261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?staticvoidkobject_init_internal(structkobject*kobj)if(!kobj)return;kref_init(&kobj-kref);/*引用計(jì)數(shù)加一*/INIT_LIST_HE
47、AD(&kobj-entry);/*初始化鏈表*/kobj-state_in_sysfs=0;kobj-state_add_uevent_sent=0;kobj-state_remove_uevent_sent=0;kobj-state_initialized=1;/*已經(jīng)初始化*/cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/arti
48、cle/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?staticvoidkobject_init_internal(structkobject*kobj)if(!kobj)return;kref_init(&kobj-kref);/*引用計(jì)數(shù)加一*/INIT_LIST_HEAD(&kobj-entry);/*初始化鏈表*/kobj-state_in_sysfs=0;kobj-state_add_uevent_sent=0;kobj-state_remove_uevent_sen
49、t=0;kobj-state_initialized=1;/*已經(jīng)初始化*/建立sd樹(shù)cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?staticintkobject_add_inter
50、nal(structkobject*kobj)interror=0;structkobject*parent;if(!kobj)return-ENOENT;if(!kobj-name|!kobj-name0)WARN(1,kobject:(%p):attemptedtoberegisteredwithemptyname!n,kobj);return-EINVAL;/*如果kobj的parent存在,增加其引用計(jì)數(shù)*/parent=kobject_get(kobj-parent);/*joinksetifset,useitasparentifwedonotalreadyhaveone*/if(k
51、obj-kset)if(!parent)/*如果其parent不存在,那么用kset中的kobject作為其parent,這里可以看出kset-kobj的parent為自身*/parent=kobject_get(&kobj-kset-kobj);kobj_kset_join(kobj);/*加入kset鏈表*/kobj-parent=parent;/*初始化parent字段*/pr_debug(kobject:%s(%p):%s:parent:%s,set:%sn,kobject_name(kobj),kobj,_func_,parent?kobject_name(parent):,kobj
52、-kset?kobject_name(&kobj-kset-kobj):);error=create_dir(kobj);/*為kobj創(chuàng)建dir以及屬性樹(shù),sd結(jié)構(gòu)表示*/if(error)/*出錯(cuò)釋放資源*/kobj_kset_leave(kobj);kobject_put(parent);kobj-parent=NULL;/*benoisyonerrorissues*/if(error=-EEXIST)printk(KERN_ERR%sfailedfor%swith-EEXIST,donttrytoregisterthingswiththesamenameinthesamedirecto
53、ry.n,_func_,kobject_name(kobj);elseprintk(KERN_ERR%sfailedfor%s(%d)n,_func_,kobject_name(kobj),error);dump_stack();elsekobj-state_in_sysfs=1;/*表示kobj已經(jīng)在sysfs中*/returnerror;cpp HYPERLINK /bailyzheng/article/details/8043500 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy c
54、opy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?staticintkobject_add_internal(structkobject*kobj)interror=0;structkobject*parent;if(!kobj)return-ENOENT;if(!kobj-name|!kobj-name0)WARN(1,kobject:(%p):attemptedtoberegisteredwithemptynam
55、e!n,kobj);return-EINVAL;/*如果kobj的parent存在,增加其引用計(jì)數(shù)*/parent=kobject_get(kobj-parent);/*joinksetifset,useitasparentifwedonotalreadyhaveone*/if(kobj-kset)if(!parent)/*如果其parent不存在,那么用kset中的kobject作為其parent,這里可以看出kset-kobj的parent為自身*/parent=kobject_get(&kobj-kset-kobj);kobj_kset_join(kobj);/*加入kset鏈表*/ko
56、bj-parent=parent;/*初始化parent字段*/pr_debug(kobject:%s(%p):%s:parent:%s,set:%sn,kobject_name(kobj),kobj,_func_,parent?kobject_name(parent):,kobj-kset?kobject_name(&kobj-kset-kobj):);error=create_dir(kobj);/*為kobj創(chuàng)建dir以及屬性樹(shù),sd結(jié)構(gòu)表示*/if(error)/*出錯(cuò)釋放資源*/kobj_kset_leave(kobj);kobject_put(parent);kobj-parent
57、=NULL;/*benoisyonerrorissues*/if(error=-EEXIST)printk(KERN_ERR%sfailedfor%swith-EEXIST,donttrytoregisterthingswiththesamenameinthesamedirectory.n,_func_,kobject_name(kobj);elseprintk(KERN_ERR%sfailedfor%s(%d)n,_func_,kobject_name(kobj),error);dump_stack();elsekobj-state_in_sysfs=1;/*表示kobj已經(jīng)在sysfs中*
58、/returnerror;cpp HYPERLINK /bullbat/article/details/7259261 o view plain view plain HYPERLINK /bullbat/article/details/7259261 o copy copy HYPERLINK /bullbat/article/details/7259261 o print print HYPERLINK /bullbat/article/details/7259261 o ? ?/*addthekobjecttoitsksetslist*/staticvoidkobj_kset_join(
59、structkobject*kobj)if(!kobj-kset)return;/*增加kset-kobj的引用計(jì)數(shù),從這里可以看出,kset的引用計(jì)數(shù)為kset中kobj屬性的引用計(jì)數(shù)*/kset_get(kobj-kset);spin_lock(&kobj-kset-list_lock);/*鏈表上鎖*/list_add_tail(&kobj-entry,&kobj-kset-list);/*將kobject加入kset鏈表*/spin_unlock(&kobj-kset-list_lock);cpp HYPERLINK /bailyzheng/article/details/804350
60、0 o view plain view plain HYPERLINK /bailyzheng/article/details/8043500 o copy copy HYPERLINK /bailyzheng/article/details/8043500 o print print HYPERLINK /bailyzheng/article/details/8043500 o ? ?/*addthekobjecttoitsksetslist*/staticvoidkobj_kset_join(structkobject*kobj)if(!kobj-kset)return;/*增加kset-
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 藥品統(tǒng)一配送管理制度
- 藥品銷售績(jī)效管理制度
- 藥店加盟合同管理制度
- 藥店星級(jí)員工管理制度
- 菏澤思源學(xué)院管理制度
- 論述清朝官吏管理制度
- 設(shè)備制造公司管理制度
- 設(shè)備強(qiáng)制報(bào)廢管理制度
- 設(shè)備日常運(yùn)行管理制度
- 設(shè)備維修電工管理制度
- 醫(yī)師職業(yè)素養(yǎng)課件
- 電網(wǎng)工程設(shè)備材料信息參考價(jià)2025年第一季度
- 2024年安徽省初中學(xué)業(yè)水平考試生物試題含答案
- Python試題庫(kù)(附參考答案)
- 2024年浙江省中考英語(yǔ)試題卷(含答案解析)
- 移動(dòng)取消寬帶委托書(shū)
- 中國(guó)銀行營(yíng)業(yè)網(wǎng)點(diǎn)基礎(chǔ)服務(wù)禮儀規(guī)范
- SCR脫硝反應(yīng)器尺寸修改后
- LANTEK蘭特鈑金軟件手冊(cè)(上)
- 混凝土強(qiáng)度增長(zhǎng)曲線
- 建筑變形測(cè)量規(guī)范JGJ
評(píng)論
0/150
提交評(píng)論