1. 程式人生 > >從面向物件的角度看Linux裝置模型

從面向物件的角度看Linux裝置模型

int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)

kobj_type中的另外一個重要成員是release()函式指標。當kobject的引用計數為零時該函式指標所指向的函式就會被呼叫,用於釋放相應的系統資源(一般來說是free memory)。由於kobject一般都是內嵌成員,在釋放記憶體時應當釋放所有的記憶體而非kobject自己,所以release指標會被kobj_ktype的派生類bus_ktype或device_ktype或driver_ktype過載。由於這種派生不屬於內嵌物件,所以在kobj_ktype和派生類直接的連線上沒有標註。

kset

struct kset {
        struct list_head list;
        spinlock_t list_lock;
        struct kobject kobj;
        const struct kset_uevent_ops *uevent_ops;
};
由於kset中內嵌了kobject,這兩個結構使用表示繼承關係的連線表示。在連線處標註了kobj,表示kobject在kset中的內嵌物件名為kobj。 kset是一種容器型別,它的list成員串起了多個kobject,其中每個kobject的kset *kset指標又指向了kset。 kobject的parent和ket指標具有不同的含義。parent指向其在/sys裡的父目錄,而kset只是表示它所處的容器(可以為空)。例如每一個device的parent都指向父device,而從圖上可以看出kset都指向devices_kset(表示包含所有device的容器)。 在呼叫kobject_add()時,如果parent為空,則parent將會被賦值為kobject的kset指標,這時兩個指標(parent和kset)就指向相同的object。在圖中,如果一個結構體的parent指標沒有標出,則代表kset指標與parent指標相同。例如對bus_type結構體,它的parent和kset指標都指向bus_kset變數。

bus_type

圖中的bus_type類其實表示的是實際程式碼中的bus_type結構體加上subsys_private結構體。由於這兩個結構體共同描述了一條bus,並且兩個結構體中分別有指標指向對方,所以將它們作為一個整體考慮。 所有的bus_type的kset和parent指標(其實這些指標包含在bus_type所內嵌的kobject結構內)都指向一個叫做bus_kset的變數。這個變數就代表了/sys/bus目錄。因此我們能夠在該目錄下找到所有註冊過的bus的目錄。 在but_type中有兩個kset成員分別是devices_kset和drivers_kset,它們代表了相應bus目錄下的devices和drivers目錄。例如在/sys/bus/usb/下就有devices和drivers目錄。 另外還有兩個klist型別的成員是klist_devices和klist_drivers。這兩個連結串列分別串起了該bus所包含的的所有裝置和驅動。 bus_type相關的三個重要API分別是bus_register, device_register和driver_register。通過命名它們的含義已經非常清晰。

device

圖中的device結構代表了實際程式碼中的device結構和device_private結構。將兩者合併的原因與合併bus_type和subsys_private的原因一致。

每一個裝置都內嵌(或者說繼承)了一個device結構體。device結構中的bus指標指向相應的bus_type結構。driver指標則指向相應的device_driver結構。在表示多對一的關係時(一端為菱形的直線),標註表示了參與該關係的成員名稱。以device和device_driver的關係為例,標註為"n:driver  1:klist_devices",其中"n:driver"表示多的一方(device)中的driver指標指向一的一方(device_driver),其中"1:klist_devices"表示一的一方(device_driver)中的klist_devices串起了多的一方(device)。

device結構的kset指標指向devices_kset變數,該變數代表了/sys/devices目錄。

device結構的parent指標則指向了它的父device。

device結構中的p指標指向device_private結構,其定義如下所示。其中klist_children包含了所有該device的子device。前面談到過bus和driver都有一個連結串列連線了所有相關的device,device_private中的knode_*就放在該連結串列中。driver_data指向driver相關的資料結構。

struct device_private {
        struct klist klist_children;
        struct klist_node knode_parent;
        struct klist_node knode_driver;
        struct klist_node knode_bus;
        struct list_head deferred_probe;
        void *driver_data;
        struct device *device;
};


device_driver

圖中的device_driver結構其實代表了實際程式碼中的device_driver結構和driver_private結構。將兩者合併的原因與合併bus_type和subsys_private的原因一致。每一個device driver都由一個device_driver結構代表。該結構的bus指標指向相應的bus_type結構。 該結構包含許多函式指標成員用於被不同的裝置驅動過載,以實現相應的功能。

bus_ktype, device_ktype, driver_ktype

這三種類型都派生自kobj_type類。每一種派生類都與處在同一行並具有相同顏色的結構有著緊密的關係。例如bus_type的ktype指標(包含於嵌入結構kobject)就指向bus_ktype。bus_ktype包含了與bus相關的sysfs operation函式指標,並且包含用於釋放bus_ktype的release函式指標。

bus_attribute, device_attribute, driver_attribute

以bus_attribute為例,它通過包含attribute結構實現了對它的繼承。每一個attribute都代表了/sys下的一個檔案(又稱作attribute)。struct attribute定義了這個檔案的名稱、許可權等資訊。另外兩個函式指標則指向了讀寫該檔案(attribute)時將會呼叫的函式。
struct bus_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct bus_type *bus, char *buf);
        ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};
bus_attribute與bus_ktype是一種緊密協作的關係。以bus_register()中的程式碼為例,當下面的bus_create_file()被呼叫時,bus_attr_uevent將被作為bus的一個attribute註冊在核心裡,同時會有一個uevent檔案新增在bus的目錄下。
<pre name="code" class="cpp"><pre name="code" class="cpp">int bus_register(struct bus_type *bus)
{
	// ...
	retval = bus_create_file(bus, &bus_attr_uevent);
}

struct bus_attribute bus_attr_uevent = {
<span style="white-space:pre">	</span>{.name = "uevent", .mode = S_IWUSR},
<span style="white-space:pre">	</span>.show = NULL,
<span style="white-space:pre">	</span>.store = bus_uevnet_store,
}
當程序寫uevent檔案時,bus_type所對應的ktype(即bus_ktype)中的sysfs_op指向的函式就會被呼叫(例如bus_attr_show())。傳入的kobj和attr引數分別是bus_type和bus_attribute的內嵌成員。bus_attr_show()就會相應的將它們轉換成相應型別(即bus_type和bus_attribute)的指標,並且呼叫bus_attribute裡的store函式指標,也就是bus_uevent_store。

相關推薦

面向物件角度Linux裝置模型

int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) kobj_type中的另外一個重要成員是release()函式指標。當kobject的引用計數為零時該函式指標所指向的函式就會被呼叫,用於釋放相應的系統資源

面向物件角度前端工程體系

寫在前面 從面向過程的角度來看前端工程,就是各個過程,以及過程之間的銜接: (面向過程視角下的)前端工程 = 過程 + 過程間的銜接 其中,過程旨在解決效率問題,而過程間銜接關注更多的是體驗問題,前端工作流相關的所有工程設施都可以按這個標準來劃分,要麼是過程,要麼是銜接 反過來從問題角度看,體驗問題能夠通過

深入剖析Spring(一)——IoC的基本概念(面向物件角度介紹)

IoC與DI IoC和DI是Spring的兩個核心概念,很多人都把它們視為相同的東西,但事實並非如此。 IoC(Inversion of Control):控制反轉。 DI(Dependency Injection):依賴注入。 為了方便理解,先給出

面向物件地分析Linux核心裝置驅動(2)——Linux核心裝置模型與匯流排

Linux核心裝置模型與匯流排 -         核心版本 Linux Kernel 2.6.34, 與 Robert.Love的《Linux Kernel Development》(第三版)所講述的核心版本一樣 1.      Linux核心裝置模型分析 1)  

CPU cache一致性的角度Linux spinlock的不可伸縮性(non-scalable)

凌晨一點半的深圳雨夜: 豪雨當夜驚起有人賞,笑嘆落花無聲空飄零。 喜歡這種豪雨,讓人興奮。驚起作文以嗚呼之感嘆! 引用上一篇文章: 優化多核CPU的TCP新建連線效能–重排spinlock:https://blog.csdn.net/dog250

進化的角度為啥要均貧富

從進化的角度看為啥要均貧富   柳鯤鵬 2008-2-20   關鍵字:進化 變異 數量 均貧富 簡介:人的存在,就是要進化到更高的層次,這主要靠變異。而變異就要靠數量才能維護。只有保證社會絕大多數人的正常生活,人類社會才能正常進化。所以要均貧富。       關

夯實Java:面向物件說起

作者:伯特出處:github.com/ruicbAndroi…宣告:本文出自伯特的《LoulanPlan》,轉載務必註明作者及出處。 剛學習 Java 那會就接觸了“面向物件”的概念,但當時並沒有太多實戰經驗,所以對其的理解也僅限於概念。當工作兩年後再回顧一下,有些概念能夠落地了,遂記錄

行業的角度分析-Linux運維工程師

Linux運維工程師是一個新穎崗位,現在非常吃香,目前從行業的角度分析,隨著國內軟體行業不斷髮展壯大,越來越多複雜系統應運而生,為了保證系統穩定執行,必須要有足夠多的Linux運維工程師。維護是軟體生命週期中非常重要一個階段,當前國內的運維工程師人才相對稀缺,故在未來幾年,運維工程師肯定會成

互聯網+角度雲計算的現狀與未來(2)

大數據平臺 堅強 隱藏 用戶管理 圖像識別 都是 人工智能 大致 統計數據 此文已由作者劉超授權網易雲社區發布。歡迎訪問網易雲社區,了解更多網易技術產品運營經驗。六、業務架構趨勢一:互聯網沖擊已成必然,快速變更成為核心競爭力,DevOps重構組織架構,流程,文化是必然選擇在

概率的角度logistic regression

logistic regression假設樣本 x x x為正的概率是:

02 JDK原始碼角度Boolean

Java的Boolean類主要作用就是對基本型別boolean進行封裝,提供了一些處理boolean型別的方法,比如String型別和boolean型別的轉換。 主要實現原始碼如下圖所示,具體實現程式碼可自行檢視對應的程式碼。 既然是對基本型別boolean的封裝,那

面向物件分析的三個模型和五個層次

在面向物件分析中,主要由物件模型、動態模型和功能模型組成。物件模型是最基本、最重要、最核心的。   用面向物件方法開發軟體,通常需要建立3種形式的模型,它們分別是描述系統資料結構的物件模型,描述系統控制結構的動態模型和描述系統功能的功能模型。一個典型的軟體系統使用資料結構(物件模型),執行操作(

JDK 原始碼角度 Object

Java的Object是所有其他類的父類,從繼承的層次來看它就是最頂層根,所以它也是唯一一個沒有父類的類。它包含了物件常用的一些方法,比如getClass、hashCode、equals、clone、toString、notify、wait等常用方法。所以其他類繼承了Obje

【轉】架構之路:管理者的角度問題

  http://www.cnblogs.com/freeflying/p/6036910.html 同步釋出在知乎,也不知道在部落格園裡這算不算水文,能不能上首頁。但園子裡還有一千多粉絲,我主要是想通知下面這件事:   +++++++++++++++++++ 這個系列寫得很坎坷

另一個角度事件驅動和協程

有一些新的想法,可能大部分的軟體架構就是人的活動的一種抽象。比如事件驅動,就可以從人的日常活動中提煉出來,設想一個禮拜天你在家裡打遊戲/上網,這個時候你媽媽打電話過來說外面下雨了,讓你去收衣服,這就是一個典型的事件驅動,你這個時候去收衣服,就是執行了回撥函式,如果不去收繼續打遊戲,就是出了B

08-1 線性變換角度叉積

I.問題描述 我們在08小節給出一個計算三維向量叉積的公式,但是這個公式為啥是那樣呢? 為啥這樣計算出的向量滿足三條性質呢? (1).長度=平行四邊形的面積 (2).方向垂直於向量v和向量u (3).滿足右手定則 通過公式推理,我們可

linux裝置模型十(bus_device_driver總結)

前面九章分別對linux驅動模型中的細節部分進行了分析,本節作為小節,使用一個簡單的例子,分別使用前面分析的內容,實現一個簡單的匯流排,裝置,驅動之間的關係。   實現一條匯流排 #include <linux/device.h> #include <li

linux裝置模型的inode,cdev,kobj_map,char_device_struct

Char Device Driver   相關資料結構: struct cdev {   struct kobject kobj;   struct module *owner;   const struct file_operations *ops;   str

深入理解閉包系列第二篇——執行環境角度閉包

前面的話   本文從執行環境的角度來分析閉包,先用一張圖開宗明義,然後根據圖示內容對程式碼進行逐行說明,試圖對閉包進行更直觀的解釋 圖示 說明   下面按照程式碼執行流的順序對該圖示進行詳細說明 function foo(){ var a = 2; funct

Linux裝置模型之tty驅動架構分析

------------------------------------------ 本文系本站原創,歡迎轉載!轉載請註明出處:http://ericxiao.cublog.cn/------------------------------------------一:前言Tty這個名稱源於電傳打位元組的簡稱。