linux裝置驅動2

2021-07-11 22:42:48 字數 4439 閱讀 3482

原文出處:

這仍然是摘自自己工作筆記的第二部分,主要記述了我對在核心中註冊驅動程式(我們這裡以我的sdio匯流排及wlan網絡卡舉例)後,在核心中呼叫了哪些核心函式?其相應的裝置樹是如何形成的?以及我看《linux裝置驅動第三版》linux裝置模型章節的諸多疑惑的總結。仍然要強調一遍,這裡僅僅是我的理解而已,正確與否我無法判斷。所以對軍爺問題的回答,也希望軍爺和我多多**。

首先我要做的是總領一下

kobject、kset、subsystem 這三個結構之間的關係。同樣以下內容摘自我的工作筆記,但順序顛倒了,這裡先行介紹可能對我們之後的**介紹要有些許幫助。 關於

kobject

結構,首先

每個目錄代表乙個

kobject

物件,每個檔案代表

kobject

的屬性(這裡我實在不敢肯定!)。kobject

是組成裝置模型的基本結構,它只是乙個類似

c++中基類的東西。

我想給出這樣乙個比喻(我不知道這個比喻是否恰當):對於每乙個目錄,它們都有一些共同的特點,比如都有名字,都有父子目錄。而對於「方法」來說,它們都 有用來實現引用計數的方法。我們將這些共同點封裝起來形成了基類。但是這個基類並不能真正的代表乙個目錄,加上了其它的特徵之後才能成為乙個真正的目錄, 所以我們需要將

kobject

這個結構嵌入所有的

sysfs

下的目錄中以獲得

kobjec

t 提供的一些特徵,在加上每個目錄自己所獨有特徵從而形成乙個

sysfs

中的目錄。這也就是我理解的kobject 結構的意義。那麼kobject 結構是否真的就對應於乙個目錄呢?回答是肯定的,因為我在**中找到了這樣的答案,每一次呼叫kobject_add 函式,都會在這個函式中呼叫create_dir 來建立乙個目錄。

那麼kset 又是什麼呢?為什麼需要kset ?還有subsystem 呢?kobject、kset、subsystem 這三個結構到底在裝置樹中各自承擔什麼樣的角色?

kset

是是嵌入相同型別結構的

kobject 的

集合,對於c++來說意味著將繼承自所有基類的子類放在一起,這有什麼意義呢?這樣想是否就會覺得很合理了,kset 是用來將所有有著共同特點的目錄聯絡在一起的東西。可能你還是要在內心不停的問,這太抽象了 太抽象了,能舉個例子嗎?是的,比如我們的裝置樹下的pci匯流排目錄/sys/bus/pci 下掛接著很多的裝置和驅動(當然有很多的裝置和驅動可以掛著在pci匯流排下),那麼我們如何將它們聯絡在一起呢?是的,是通過kset 結構,那麼kset 結構是個什麼樣的地位呢?噢,我想之前我理解錯了,它不是/sys/bus/pci 目錄,也不是/sys/bus/pci/drivers 目錄中的某個具體驅動,它剛好就是/sys/bus/pci/drivers 目錄。不相信? 那麼開啟你們的linux 作業系統,看一看是否每一條匯流排都有著drives和devices 兩個目錄?它們兩個都是嵌入了kset 結構;那麼/sys/bus/pci/drivers 目錄中的某個具體驅動呢?它就是嵌入了kobject 結構的目錄;/sys

/bus/pci 目錄呢?猜對了,它就是subsystem 結構的嵌入。 還有要補充的嗎?是呢,現在subsystem 貌似被取消了,取代它的就是kset 結構。這樣也就是說一系列的

kset

就組成了

subsystem 。

我似乎忘記了自己問了三個問題,對的,我還需要問答自己看《linux裝置驅動第三版》提出來的第三個問題:為什麼需要kset ?提出這個問題的想法很幼稚,難道我們不能夠只用kobject 結構將掛接在一條匯流排上的驅動或者裝置都鏈結在一起嗎?只要我們有list_head !linux核心的作者回答了我這個問題,你需要乙個容器來管理它們,就像c++中的容器一樣。但這至少說明了kset 並不是必要的存在。那麼kset 是如何扮演容器的角色的呢?這個問題,我們需要看後面的**來回答。

以上是摘自我穿插在工作筆記中的關於kobject、ket、subsystem三個結構的描述,可能大家讀完這段解釋仍然無法形成具體的概念,仍然覺得很抽象。沒關係,因為我在**分析之後還會有總結性的舉例。那時還不明白我就沒轍了!!!

好 了,現在我們得費勁心思的捋一遍我們的驅動註冊**,以便找到裝置樹新增的關鍵部分。我想我又得強調一下,我的介紹是sdio驅動,所以請大家看著 linux核心**drivers/mmc中關於sdio的驅動來理解我下面的筆記中的內容(想不看核心**就理解裝置樹,我想太難太難)

有關 sbi_register

函式(這是在我的wlan驅動**中的函式,並不需要你太多的關注 )中 sdio_register_driver函式(從現在開始就都是核心函式了)

註冊驅動的介紹,在 sdio_register_driver

中將會指明驅動的名稱(這裡是」wlan_sdio 」

),此函式的引數為 sdio_driver

結構。 驅動所掛接的匯流排 sdio_bus_type

,其結構型別為:

static struct bus_type sdio_bus_type = ;

這個結構將在 sdio_register_driver

函式中被賦值以產生 device_driver

結構。也就是說 device_driver

被包含在 sdio_driver

中。 隨後呼叫函式 driver_register

,其引數為 device_driver

(此結構中定義了 bus_type,也就是驅動掛接的匯流排型別

)。至此將轉入所有驅動(不止是 sdio

卡驅動)的註冊**中。此時的驅動結構已經變為device_drive (

核心定義的驅動結構 )。

driver_register

將會完成掛接驅動至匯流排及生成裝置樹的過程,其完成的任務大致包括: 1

、設定裝置驅動中 kobject

的名字

2、將 kobject

新增至 sysfs

中,也就是在 sysfs

樹中建立乙個目錄( kobject

中有乙個函式 create_dir

用於建立目錄。) 3

、呼叫 driver_attach

函式完成 probe  4

、 driver_create_file

建立檔案屬性,會生成乙個屬性為 driver_attr_uevent

的屬性檔案。 5

、 add_bind_files

生成屬性為 driver_attr_unbind

和 driver_attr_bind

的屬性檔案,關於檔案的屬性,它定義了檔案的讀寫方式。

如此抽象的描述及流水賬般的記述我發現還是很沒有說服力,因此我決定給出乙個具體的例子,並給出**的實現。先看例子——讓我們看一下 /sys/bus/

下的目錄,然後來個具體的描述:已知我們的匯流排的目錄名字為」sdio」 。也就是說在 /sys/bus 目錄下有乙個目錄叫 sdio ,即 /sys/bus/sdio

。它是怎麼形成的?核心中有 」sdio」匯流排的驅動,找到這個函式 bus_register (&sdio_bus_type ) ;就是用來註冊匯流排的。我們在前面不也看到了driver_register

函式嗎,是的,你猜對了,還有乙個函式叫 device_register

。在這個函式呼叫完成後,就會得到/sys/bus/ 目錄下的 sdio 目錄了。那麼驅動的名字 」wlan_sdio」 又是如何插入到 /sys/bus/drivers/wlan_sdio

目錄下的呢。在 driver_register->driver_register->bus_add_driver

函式中有個重要的語句 drv->kobj.kset = &bus->drivers ;

想象一下我們折騰了那麼長時間的 kobject

與 kset

的意義,是的,這裡就是將 driver

的 kobj

所屬的 kset

掛接上匯流排的 kset

。我們這裡顯得很繞對嗎?幸運的是我在網上找到了乙個非常棒的示意圖:

我該怎麼樣來形容這個圖呢? 它把依賴關係說的已經足夠清楚了!!我這裡唯一要解釋的僅僅是在驅動資料夾被正確後所謂的檔案屬性有在那裡。同樣我們順著目錄 /sys/bus/sdio/driver/wlan_sdio/

下我們發現了 bind

、unbind

和 new_id

三個檔案。

好了,別忘了我們在前面提過的問題,kset 是如何扮演容器的角色的呢?圖中很清楚吧,看看粉紅色的箭頭,kset children list用來將將同型別的kobject連線起來以達到容器的效果。

但是我們的驅動還沒有結束,關於這個圖的建立,我們勢必要用**才能說得明白。

我們還是花費一點時間來看一下核心中的**,關於

sdio

intbus_register(

struct 

bus_type * bus)

至此我們終於理順了整個過程。

Linux核心 2 裝置驅動實驗

今天做了linux課設關於裝置驅動的實驗。實驗採用模組的方法編寫乙個可以進行簡單讀寫的字元裝置驅動,該裝置可以儲存一定長的字串,寫入裝置即可以將字串存入裝置,讀出即可以獲取該字串,並編寫了測試程式對其測試。1 首先新建並編寫了字元驅動裝置chardev.c檔案,檔案 如下 建立乙個字元裝置 讀寫 必...

驅動 linux裝置驅動 字元裝置驅動開發

preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...

Linux裝置驅動

一.簡介 作業系統是通過各種驅動程式來駕馭硬體裝置,它為使用者遮蔽了各種各樣的裝置,驅動硬體是作業系統最基本的功能,並且提供統一的操作方式。正如我們檢視螢幕上的文件時,不用去管到底使用nvidia晶元,還是ati晶元的顯示卡,只需知道輸入命令後,需要的文字就顯示在螢幕上。硬體驅動程式是作業系統最基本...