linux驅動(八)驅動設備模型

http://blog.csdn.net/xiahouzuoxin/article/details/8943863html

http://blog.chinaunix.net/uid-25627207-id-3343854.htmljava

http://blog.csdn.net/phunxm/article/details/8994311linux

http://blog.csdn.net/new_abc/article/details/7558845算法

http://www.cnblogs.com/andtt/articles/2178905.html網絡

http://blog.csdn.net/heli200482128/article/details/51828745數據結構

2.6內核增長了一個引人注目的新特性——統一設備模型(device model)。設備模型提供了一個獨立的機制專門來表示設備,並描述其在系統中的拓撲結構,從而使得系統具備如下優勢:架構

(1)代碼重複最小化ide

(2)提供諸如引用計數這樣的統一機制。函數

(3)能夠列舉系統中全部的設備,觀察它們的狀態,而且查看它們鏈接的總線。ui

(4)能夠將系統中的所有設備結構以的形式完整、有效的展示出來——包括全部的總線和內部鏈接。

(5)能夠將設備和其對應的驅動聯繫起來,反之亦然。

(6)能夠將設備按照類型加以歸類,好比分類爲輸入設備,而無需理解物理設備的拓撲結構。

(7)能夠沿設備樹的葉子向其根的方向依次遍歷,以保證能以正確順序關閉各設備的電源。

最後一點是實現設備模型的最初動機,若想在內核中實現智能的電源管理,就須要來創建表示系統中設備拓撲關係的樹結構。當在樹上端的設備關閉電源時,內核必須首先關閉該設備節點如下的(處於葉子上的)設備電源。好比內核須要先關閉一個USB鼠標,而後纔可關閉USB控制器;一樣內核也必須在關閉PCI總線前先關閉USB控制器。簡而言之,若要準確而又高效的完成上述電源管理目標,內核無疑須要一顆設備樹

(注:設備模型與電源管理相關聯,貌似匪夷所思,可實際上,一個新觀點或模型出現,在其背後都是需求的刺激。最近以來,節電一直是Intel、IBM等大公司孜孜追求的目標,虛擬化技術的本質其實就是節能。或者說,在能源日趨緊張的今日,節能是人類共同追求的目標)。

爲何驅動模型有助於電源管理,再說兩句:

系統中全部硬件設備由內核全權負責電源管理。例如,在以電池供電的計算機進入「待機」狀態時,內核應馬上強制每一個硬件設備(硬盤,顯卡,聲卡,網卡,總線控制器等等)處於低功率狀態。所以,每一個可以響應「待機」狀態的設備驅動程序必須包含一個回調函數,它可以使得硬件設備處於低功率狀態。並且,硬件設備 必須按準確的順序進入「待機」狀態,不然一些設備可能會處於錯誤的電源狀態。例如,內核必須首先將硬盤置於「待機」狀態,而後纔是它們的磁盤控制器,由於若按照相反的順序執行,磁盤控制器就不能向硬盤發送命令。

Linux設備驅動模型(二)-文件系統之視圖

雖然設備模型的初衷是爲了方便電源管理而提供出的一種設備拓撲結構,可是,爲了方便調試,設備模型的開發者決定將設備結構樹導出爲一個文件系統,這就是sysfs文件系統,它能夠幫助用戶以一個簡單文件系統的方式來觀察系統中各類設備的拓撲結構。這個舉措很快被證實是很是明智的,首先sysfs代替了先前處於/proc下的設備相關文件;另外它爲系統對象提供了一個頗有效的視圖。實際上,sysfs起初被稱爲driverfs。最終sysfs使得咱們認識到一個全新的對象模型很是有利於系統。今天全部2.6內核的系統都擁有sysfs文件系統,並且幾乎都毫無例外的將其掛載。

圖一是掛載於/sys目錄下的sysfs文件系統的局部視圖。

> mount -t sysfs sysfs /sys

/sys

     |—block/

     |   |–fd0

     |   |–had

     |   |–dev

     |   |–device->../../devices/pci0000:00/0000:00:1f.1/ide0/0.0

     |    …

     |–bus/

     |–class/

     |–devices/

     |–firmware/

     |–power/

     |–module/

sysfs的根目錄下包含了七個目錄:block,bus,class,devices,firmware,module和power。

(1)block目錄下的每一個子目錄都對應着系統中的一個塊設備。反過來,每一個目錄下又都包含了該塊設備的全部分區。

(2)bus目錄提供了一個系統總線視圖。

(3)class目錄包含了以高層功能邏輯組織起來的系統設備視圖。

(4)devices目錄是系統中設備拓撲結構視圖,它直接映射出了內核中設備結構體的組織層次。

(5)firmware目錄包含了一些諸如ACPI,EDD,EFI等低層子系統的特殊樹。

(6)power目錄包含了系統範圍的電源管理數據。

(7)module目錄包含了內核模塊。模塊是一種向Linux內核添加設備驅動程序、文件系統及其餘組件的有效方法。

其中最重要的目錄是devices,該目錄將設備模型導出到用戶空間。目錄結構就是系統中實際的設備拓撲。其它目錄中的不少數據都是將devices目錄下的數據加以轉換加工而得。好比,/sys/class/net/目錄是以註冊網絡接口這一高層概念來組織設備關係的,在這個目中可能會有目錄eth0,它裏面包含的devices文件其實就是一個指回到devices下實際設備目錄的符號鏈接。

隨便看看任何你可訪問到的Linux系統,這種系統設備視圖至關準確和漂亮,並且能夠看到class中的高層概念與devices中的低層物理設備,以及bus中的實際驅動程序之間互相聯絡是很是普遍的。

Linux設備驅動模型(三)-追根之溯源

軟件設計的根本是把現實世界的事物用計算機世界的模型表示出來,Linux設備模型的設計採用了面向對象(Object Oriented)的思想。

在前一講中,提到sysfs文件系統,sysfs文件系統的目標就是要展示設備驅動模型組件之間的層次關係。在Linux中,sysfs文件系統被安裝於/sys目錄下,見上圖一。那麼,在這樣的目錄樹中,哪些目錄是驅動模型要關注的對象

bus-系統中用於鏈接設備的總線,在內核中對應的結構體爲structbus_type { …  };

device-內核所識別的全部設備,依照鏈接它們的總線對其進行組織,對應的結構體爲struct device {…  };

class-系統中設備的類型(聲卡,網卡,顯卡,輸入設備等),同一類中包含的設備可能鏈接到不一樣的總線,對應的結構體爲struct class{…  };

爲何不對Power進行單獨描述?實際上,Power與device有關,它只是device中的一個字段

除此以外,立馬閃如今咱們腦子裏的對象還有:driver-在內核中註冊的設備驅動程序,對應的結構體爲struct device_driver{…  };

以上bus,device,class,driver是能夠感覺到的對象,在內核中都用相應的結構體來描述。而實際上,按照面向對象的思想,咱們須要抽象出一個最基本的對象,這就是設備模型的核心對象kobject

kobject是Linux 2.6引入的新的設備管理機制,在內核中就是一個struct kobject結構體。有了這個數據結構,內核中全部設備在底層都具備統一的接口,kobject提供基本的對象管理,是構成Linux2.6設備模型的核心結構,它與sysfs文件系統緊密關聯,每一個在內核中註冊的kobject對象都對應於sysfs文件系統中的一個目錄kobject是組成設備模型的基本結構。相似於C++中的基類,比如MFC中的CObject、Java中的Object和COM中的IUnKnown。kobject嵌入於更大的對象中,即所謂的容器,如上面提到的bus,class,devices,drivers都是典型的容器,它們是描述設備模型的組件

---------------------------------------------------------------------------------------------------------------------------------------------------

kobj:

Linux內核裏,kobject是組成Linux設備模型的基礎,一個kobject對應sysfs裏的一個目錄。從面向對象的角度來講,kobject能夠看做是全部設備對象的基類,由於C語言並無面向對象的語法,因此通常是把kobject內嵌到其餘結構體裏來實現相似的做用,這裏的其餘結構體能夠看做是kobject的派生類。Kobject爲Linux設備模型提供了不少有用的功能,好比引用計數,接口抽象,父子關係等等,因此,在內核中,沒有用kobject直接定義的變量,kobject只是做爲一個抽象的基類而存在。通常都是將kobject嵌入到另外一個結構,這個結構就能夠看作是kobject的一個子類。而kobject的子類會比較關心kobject的屬性和方法。

內核裏的設備之間是以樹狀形式組織的,在這種組織架構裏比較靠上層的節點能夠看做是下層節點的父節點,反映到sysfs裏就是上級目錄和下級目錄之間的關係,在內核裏,正是kobject幫助咱們實現這種父子關係。在kobject的定義裏,name表示的是kobject在sysfs中的名字;指針parent用來指向kobject的父對象;Kref你們應該比較熟悉了,kobject經過它來實現引用計數;Kset指針用來指向這個kobject所屬的kset;對於ktype,若是隻是望文生義的話,應該是用來描述kobject的類型信息。

-----------------------------------------------------------------------------------------------------------------------------------------------------------

kset:

有時候,某個設備的可能具備多個kobject的子類對象,或者某些設備具備相同的特性,爲了便於管理,應該把這些對象統一放入一個容器中。這裏要用到的容器就是kset。kset只是kobject的一個集合。對應到Linux文件系統中,一個kset就是/sys下的一個文件夾。

Kset自己也是一個kobject,因此它在sysfs裏一樣表現爲一個目錄,但它和kobject的不一樣之處在於kset能夠看做是一個容器,若是你把它類比爲C++裏的容器類如list也無不可。Kset之因此能做爲容器來使用,其內部正是內嵌了一個雙向鏈表結構struct list_head

 

kset 象 kobj_type 結構的擴展; 一個 kset 是嵌入到相同類型結構的 kobject 的集合。但 struct kobj_type 關注的是對象的類型,而struct kset 關心的是對象的聚合和集合,其主要功能是包容,可認爲是kobjects 的頂層容器類。每一個 kset 在內部包含本身的 kobject, 並能夠用多種處理kobject 的方法處理kset。 ksets 老是在 sysfs 中出現; 一旦設置了 kset 並把它添加到系統中, 將在 sysfs 中建立一個目錄;kobjects 沒必要在 sysfs 中表示, 但kset中的每個 kobject 成員都在sysfs中獲得表述。

kobject創建的目錄下只能添加文件,
kset創建的目錄下添加目錄,
kset是具備相同類型的kobject的集合。

-----------------------------------------------------------------------------------------------------------------------------------------------------------

kobj與kset的關係

咱們看一下sys目錄下的文件:

每一個文件夾都對應一個kobject,/sys/目錄下的文件夾是kset中包含的kobject,

sys目錄下的全部文件夾都是一個層次的,每一個文件夾都是一個kset,每一個kset->object 都指向sys的kset以及kset->kobject;

在追蹤到子目錄中:

如class目錄:

這裏的每個文件夾也都是一個kset,這個文件夾是在一個層次上的;

每一個kset->object 都指向class的kset以及kset->kobject;

追到最底層的文件夾對應一個kobject,kobject中的文件就是kstyle中的attribute;

設備模型就是這麼一層層創建起來的;

-----------------------------------------------------------------------------------------------------------------------------------------------------------

相關文章
相關標籤/搜索