linux核心之裝置驅動那些事(1)

2021-07-27 02:17:50 字數 3288 閱讀 7474

linux核心,作為作業系統的核心部分,管理各種硬體資源。核心對上遮蔽各種底層細節,簡化應用程式開發。

核心中有相當比例的**為驅動**,因為核心需要支援各種各樣的硬體。每次核心正式版本的發布,驅動**所佔比例總是最多。眾多硬體廠商將驅動**提交到核心開源版本中,並遵從核心驅動架構,除開利益因素,必然意味著驅動架構有其合理之處。

接下來,希望能通過對驅動各個部分和細節的了解,逐步加深對其的理解,終極目標是有改造它,優化它的能力。

linux核心中有常見的三種典型裝置:

所有字元裝置和塊裝置都有主從裝置號:

乙個裝置具體屬於哪一種裝置,關鍵是看其如何被應用所使用。

框架:使硬體特性以某種通用的方式供上層使用。應用必然不會直接操作硬體,甚至根本不知道底層有哪些硬體。通過檔案系統使用塊裝置;通過socket利用核心協議棧使用網路介面,這裡檔案系統、核心協議棧就是框架。

匯流排:是核心驅動模型的重要組成部分,實現硬體和驅動的匹配,建立起硬體與驅動之間的聯絡

驅動開發在已經對硬體本身比較了解的基礎上,只要知道以什麼方式將硬體資源體現給應用(使用什麼框架),以什麼匯流排形式註冊到核心中,就可以專注在驅動的實現了。

一台pc,乙個嵌入式裝置,從硬體組成上看,各種裝置、控制器都是由匯流排連線起來的,匯流排起到了連線通訊的目的。cpu到ddr的系統匯流排,pci控制到pci裝置的pci匯流排,usb控制器到usb裝置的usb匯流排,以及scsi控制器到磁碟裝置的scsi匯流排等。

核心中的匯流排,屬於軟體層面,雖然是軟體層面,但基本還是能夠和硬體層面對應起來。核心總的匯流排也是相當豐富,usb、i2c、spi、pci,還有特殊的platform匯流排。核心匯流排,最關鍵的作用就是能夠進行驅動和硬體裝置的匹配。

在linux核心中,裝置(描述)資訊和驅動是分開的,相同型別的裝置在不同系統中,資源描述資訊是不一樣的,例如暫存器位址區間、中斷號、管腳資訊等。雖然這些資訊不一樣的,但是對這類裝置的使用方式卻是相同的,完全可以做到同一套**(驅動)復用。因此核心中的驅動程式一般被設計成比較通用的形式以便能夠適應各種不同。既然裝置描述和驅動是分開的,驅動和裝置之間的聯絡則通過匯流排來完成。

由於匹配的需要,裝置資訊和驅動都需要註冊到相同型別的匯流排上。假設bus中已經註冊了裝置資訊,當驅動進行註冊時,會查詢是否有其支援的硬體,如果找到,則開始對硬體進行進一步的初始化等操作;如果沒有找到,則什麼也不用做。相反,如果bus總已經註冊了驅動,當裝置進行註冊時,會查詢是否有支援它的驅動,如果找到,則進行下一步動作;如果沒有,也是什麼也不用做。

匯流排進行裝置和驅動的匹配使用的資訊多樣,可以是相同名字的字串,也可以是相同的id號等等

下面,通過乙個具體的例子看看驅動與裝置的匹配過程:

通常核心啟動過程中會載入核心支援的驅動**模組,這時也就將相應驅動註冊到了匯流排上(當然,也有驅動模組是後續通過udev等機制動態載入的,我們後面逐一介紹)。假設上圖drivera、driverb和driverc在系統啟動過程中已經註冊到usb匯流排上。當乙個usb裝置接入時,會是乙個怎樣的過程了?

前兩個步驟為硬體層面,後面兩個則為核心軟體層面。

上面描述的usb匯流排上裝置和驅動的匹配與物理匯流排關係緊密,或者說物理匯流排對裝置的列舉識別促使該種型別對應核心匯流排的裝置和驅動的匹配呈現出我們現在看到的樣子。我們再來看另外一種匯流排,pci匯流排。由於物理上匯流排對裝置的識別與usb存在區別,因此裝置與驅動的匹配過程又呈現另一番景象。

usb和pci由於物理匯流排執行機制的差別,導致軟體上裝置與驅動的匹配呈現區別。usb看起來是usb裝置註冊時進行的匹配,而pci則是在pci驅動註冊時進行的匹配。而實際情況是,usb匯流排裝置與驅動的匹配既可以是usb裝置註冊時,也可以是usb驅動註冊時。但pci通常只能是在pci驅動註冊時進行匹配。(pci裝置的載入發生在pci控制器的掃瞄階段,pci控制器的掃瞄通常在linux核心啟動階段進行,將所有掃瞄到的pci裝置都先註冊到pci核心匯流排上,因此pci驅動通常都是在裝置註冊到匯流排後載入的)。

我們描述了能夠利用匯流排物理特性進行列舉的pci和usb的裝置和驅動的匹配過程。那麼問題來了,usb控制器了?pci控制器了?還有嵌入式系統中大量存在的外設控制器?沒有物理特性通知核心這些裝置的到來,也就無從談起註冊到核心匯流排中,它們如何匹配自己的驅動了?答案就是platform匯流排

platform匯流排是核心提供的虛擬匯流排,能夠解決上面提到的所有問題。因為沒有硬體機制或者說硬體事件能夠讓核心發現這些外設(串列埠控制器、i2c控制器、spi控制器、網口控制器、圖形裝置、聲音裝置,包括usb控制器和pci控制器等),因此核心中設計了platform匯流排,硬體資訊以dtb或者**描述的方式註冊到platform匯流排上。這些外設的驅動模組在載入時通過platform匯流排完成驅動與硬體裝置的匹配。特別是嵌入式系統中,platform匯流排是整個驅動過程的基礎。

下圖為乙個硬體系統的匯流排結構:

如果在linux核心中,對應的軟體匯流排結構大概會是這樣:

framework(框架),是我們下一節關心的內容。

核心中匯流排相關的資料結構關鍵的有三個:

1、bus_type:描述一種型別的匯流排

2、device_driver:表示匯流排上的驅動

3、device:表示匯流排上的裝置

實際上由於裝置與驅動的多樣,核心設計上,具體的驅動和裝置結構體繼承自device_driver和device結構體,達到多樣化,定製化。

到此,我們基本了解了linux核心的匯流排,從驅動**的角度看,也僅僅是完成了驅動**中probe函式被呼叫之前的過程講解。下一節,繼續probe函式後續分析。

Linux核心之字元裝置驅動

學習計畫 1.vfs 虛擬檔案系統 vfs的作用就是採用標準的unix系統呼叫讀寫位於不同物理介質上的不同檔案系統。vfs是乙個可 以讓open read write 等系統呼叫不用關心底層的儲存介質和檔案系統型別就可以工作的 粘合層。在古老的dos作業系統中,要訪問本地檔案系統之外的檔案系統需要使...

Linux核心裝置驅動註冊

platform device與platform driver 引入devicetree後改變 platform device會由kernel自動展開,呼叫of platform bus probe null,of bus ids,null 即可自動展開所有的platform device 引入de...

Linux裝置驅動 核心開發

linux裝置驅動需要使用核心api來實現,一般被包含在linux核心原始碼樹中。驅動可以編譯到核心,隨著核心一起在系統啟動的時候被載入。也可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動 的除錯。但並不是只有裝置驅動才能...