轉載自:http://www.wowotech.net/device_model/13.htmlhtml
在「Linux內核的總體架構」中,蝸蝸有提到,因爲Linux支持世界上幾乎全部的、不一樣功能的硬件設備(這是Linux的優勢),致使Linux內核中有一半的代碼是設備驅動,並且隨着硬件的快速升級換代,設備驅動的代碼量也在快速增加。我的意見,這種現象打破了「簡潔就是美」的理念,是醜陋的。它致使Linux內核看上去很是臃腫、雜亂、不易維護。但蝸蝸也知道,這不是Linux的錯,Linux是一個宏內核,它必須面對設備的多樣性,並實現對應的驅動。linux
爲了下降設備多樣性帶來的Linux驅動開發的複雜度,以及設備熱拔插處理、電源管理等,Linux內核提出了設備模型(也稱做Driver Model)的概念。設備模型將硬件設備概括、分類,而後抽象出一套標準的數據結構和接口。驅動的開發,就簡化爲對內核所規定的數據結構的填充和實現。數據結構
本文將會從設備模型的基本概念開始,經過分析內核相應的代碼,一步一步解析Linux設備模型的實現及使用方法。架構
硬件拓撲描述Linux設備模型中四個重要概念中三個:Bus,Class和Device(第四個爲Device Driver,後面會說)。spa
Bus(總線):Linux認爲(能夠參考include/linux/device.h中struct bus_type的註釋),總線是CPU和一個或多個設備之間信息交互的通道。而爲了方便設備模型的抽象,全部的設備都應鏈接到總線上(不管是CPU內部總線、虛擬的總線仍是「platform Bus」)。.net
Class(分類):在Linux設備模型中,Class的概念很是相似面向對象程序設計中的Class(類),它主要是集合具備類似功能或屬性的設備,這樣就能夠抽象出一套能夠在多個設備之間共用的數據結構和接口函數。於是從屬於相同Class的設備的驅動程序,就再也不須要重複定義這些公共資源,直接從Class中繼承便可。設計
Device(設備):抽象系統中全部的硬件設備,描述它的名字、屬性、從屬的Bus、從屬的Class等信息。orm
Device Driver(驅動):Linux設備模型用Driver抽象硬件設備的驅動程序,它包含設備初始化、電源管理相關的接口實現。而Linux內核中的驅動開發,基本都圍繞該抽象進行(實現所規定的接口函數)。htm
注:什麼是Platform Bus?
在計算機中有這樣一類設備,它們經過各自的設備控制器,直接和CPU鏈接,CPU能夠經過常規的尋址操做訪問它們(或者說訪問它們的控制器)。這種鏈接方式,並不屬於傳統意義上的總線鏈接。但設備模型應該具有普適性,所以Linux就虛構了一條Platform Bus,供這些設備掛靠。
Linux設備模型的核心思想是(經過xxx手段,實現xxx目的):
1. 用Device(struct device)和Device Driver(struct device_driver)兩個數據結構,分別從「有什麼用」和「怎麼用」兩個角度描述硬件設備。這樣就統一了編寫設備驅動的格式,使驅動開發從論述題變爲填空體,從而簡化了設備驅動的開發。
2. 一樣使用Device和Device Driver兩個數據結構,實現硬件設備的即插即用(熱拔插)。
在Linux內核中,只要任何Device和Device Driver具備相同的名字,內核就會執行Device Driver結構中的初始化函數(probe),該函數會初始化設備,使其爲可用狀態。
而對大多數熱拔插設備而言,它們的Device Driver一直存在內核中。當設備沒有插入時,其Device結構不存在,於是其Driver也就不執行初始化操做。當設備插入時,內核會建立一個Device結構(名稱和Driver相同),此時就會觸發Driver的執行。這就是即插即用的概念。
3. 經過"Bus-->Device」類型的樹狀結構(見2.1章節的圖例)解決設備之間的依賴,而這種依賴在開關機、電源管理等過程當中尤其重要。
試想,一個設備掛載在一條總線上,要啓動這個設備,必須先啓動它所掛載的總線。很顯然,若是系統中設備很是多、依賴關係很是複雜的時候,不管是內核仍是驅動的開發人員,都無力維護這種關係。
而設備模型中的這種樹狀結構,能夠自動處理這種依賴關係。啓動某一個設備前,內核會檢查該設備是否依賴其它設備或者總線,若是依賴,則檢查所依賴的對象是否已經啓動,若是沒有,則會先啓動它們,直到啓動該設備的條件具有爲止。而驅動開發人員須要作的,就是在編寫設備驅動時,告知內核該設備的依賴關係便可。
4. 使用Class結構,在設備模型中引入面向對象的概念,這樣能夠最大限度地抽象共性,減小驅動開發過程當中的重複勞動,下降工做量。