小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

學習Linux驅動的開發(fā),初探設備模型的概念

 lchjczw 2012-03-10

試著總結一下,學習一下,至少現(xiàn)在的我對于設備模型這個概念,幾乎完全不懂。

Linux設備模型中三個很重要的概念就是總線、設備和驅動,即bus、device、driver,而實際上內核中也定義了這么一些數(shù)據(jù)結構,分別為struct bus_type,struct device,struct device_driver,

原型定義均在include/linux/device.h中。而struct bus_type結構中兩個非常重要的成員就是kset和kobject這兩個結構體。

于是乎,Linux設備模型概念中重要的5個概念都引出來了,即設備模型

在具體實現(xiàn)方面分兩個層次:

一是底層數(shù)據(jù)結構來實現(xiàn)基本對象及其層次關系:kobjects和ksets。

二是基于這兩個底層數(shù)據(jù)結構上實現(xiàn)的設備模型:總線,設備,驅動。

一、底層數(shù)據(jù)結構:kobject,kset

kobject

結合面向對象的思維。這個kobject屬于最基礎的結構,也就是最高抽象層(有點像java中的Cobject類)。任何一個設備模型如總線,設備,驅動都屬于一個kobject 。在實現(xiàn)上這種派生關系就是在結構體中包含一個kobject的變量。

這個在層次上處理最頂層的kobject結構提供了所有模型需要的最基本的功能:

1 引用計數(shù) 用于內核維護其存在與消亡

2 sys水利模型fs表示 每個sys/下的對象對應著一個kobject。

3 熱拔插事件處理 處理設備的熱拔插事件。

Kobjects 在內核中對應有一套申請,初始化,添加,注冊,計數(shù)操縱,開釋等函數(shù) //2.6.10 struct kobject { char * k_name; //名稱 char name[KOBJ_NAME_LEN]; struct kref kref; //計數(shù) struct list_head entry;//用于連接到同類kobjects的鏈表 struct kobjectn * parent;//用于實現(xiàn)層次,指向其父對象 struct kset * kset; //用于實現(xiàn)層次,所屬的集合 struct kobj_typen * ktype;//指向對象的類型 struct dentry * dentry; //指示在sysfs中的目錄項 }; Kset和kobj_type

Kset在概念上是一個集合或者叫容器。實現(xiàn)了對象的層鍋爐模型鍋爐模型。所有屬于一個ksets的對象(kobject)的parent都指向該ksets的kobj.同時這個對象都連接到kset 的list表上。同時位于ksets層次之上的是subsys,在最新的內核中已經(jīng)取消subsys,由于它本質上也就是一個ksets。Kset有一套類似kobject的操縱,實現(xiàn)上只是進一步調用其自身kobj的相應操縱,究竟ksets本質上也是一個kobject。 //2.6.10 struct kset { struct subsystem * subsys; //在新內核中已經(jīng)沒有subsys概念了,同一用kests struct kobj_type * ktype; //類型 struct list_head list; //同一kset的鏈表 struct kobject kobj; //自身的kobjects struct kset_hotplug_ops * hotplu鍋爐模型g_ops; }; 最后 屬于同一個集合的對象可以擁有共同的屬性:ktype 。

struct kobj_type { void (*release)(struct kobject *); struct sysfs_ops * sysfs_ops; struct attribute ** default_attrs; }; 所謂的屬性更具體一點說就是一些鍵值對。并且在sysfs_ops中的show函數(shù)被文件系統(tǒng)調用來顯示sys/下面對應進口各屬性的值。

如此 ,kobjects與ksets實現(xiàn)層次樹的底層骨架。

進一步地,通過封裝這些底層結構來實現(xiàn)上層的設備驅動模型。

二、總線 設備 驅動

關于bus,關于device,關于driver,他們是如何建立聯(lián)系的呢?

基本關系扼要的概括如下:

驅動核心可以注冊多種類型的總線。

每種總線下面可以掛載很多設備。(通過kset devices)

每種總線下可以用很多設備驅動。(通過包含一個kset drivers)}

每個驅動可以處理一組設備。

這種基本關系的建立源于實際系統(tǒng)中各種總線,設備,驅動結構的抽象。

具體到usb設備就是usb core的代碼會進行整個usb系統(tǒng)的初始化,比如申請struct bus_type usb_bus_type,然后掃描usb總線,看線上連接了哪些usb設備,或者說root hub上連了哪些usb設備

,比如說連了一個usb鍵盤,那么就為它預備一個struct device,根據(jù)它的實際情況,為這個struct device賦值,并插進devices鏈表中來。又比沙盤模型如root hub上連了一個普通的hub,那么除了要為這個hub本身預備一個struct device以外,還得繼續(xù)掃描這個hub上是否又連了別的設備,有的話繼續(xù)重復之前的事情,這樣一直進行下往,直到完成整個掃描,終極就把usb_bus_type中的devices鏈表給建立了起來。

那么drivers鏈表呢?這個就不用bus方面主動了,而該由每一個driver本身往bus上面登記,或者說掛牌。具體到usb系統(tǒng),每一個usb設備的驅動程序都會有一個struct usb_driver結構體,其代

碼如下,來自include/linux/usb.h //2.6.10 struct usb_driver { struct module *owner; const char *name; int (*probe) (struct usb_inte***ce *intf, const struct usb_device_id *id); void (*disconnect) (struct usb_inte***ce *intf); int (*ioctl) (struct usb_inte***ce *intf, unsigned int code, void *buf); int (*suspend) (struct usb_inte***ce *intf, u32 state); int (*resume) (struct usb_inte***ce *intf); const str沙盤模型//" title="沙盤模型" target="_blank ">沙盤模型uct usb_device_id *id_table; struct device_driver driver; }; bus和device之間是如何建立聯(lián)系的?

看似很長一段,實際上也就是注釋為主.而此刻我們只需留意到其中的struct device_driver driver這個成員,usb core為每一個設備驅動預備了一個函數(shù),讓它把自己的這個

struct device_driver driver插進到usb_bus_type中的drivers鏈表中往.而這個函數(shù)正是我們此前看到的usb_register.而與之對應的 usb_deregister所從事的正是與之相反的工作,把這個結構

體從drivers鏈表中刪除.可以說,usb core的確是專心良苦,為每一個usb設備驅動做足了作業(yè),正由于如此,作為一個實際的usb設備驅動,它在初始化階段所要做的事情就很少,很簡單了, 直接調用

usb_register即可.事實上,沒有人是理所當然應該為你做什么的,但usb core這么做了.所以每一個寫usb設備驅動的人應該銘記,usb device driver盡不是一個人在工作,在他身后,是usb core所提

供的默默無聞又不可或缺的支持。

device和driver之間是如何建立聯(lián)系的呢?

由于有了熱插拔,device可以在計算機啟動以后在插進或者拔出計算機了.因此,很難再說是先有device還是先有driver了.由于都有可能.device可以在任何時刻出現(xiàn),而driver也可以在任何時刻被加載,所以,出現(xiàn)的情況就是,每當一個struct device誕生,它就會往bus的drivers鏈表中尋找自己的另一半,反之,每當一個一個struct device_driver誕生,它就往bus的devices鏈表中尋找它的那些設備.假如找到了合適的,那么ok,調用 device_bind_driver綁定好.假如找不到,沒有關系,等待吧。

還記得初始化的那幾行代碼嗎?回到usb_register中來,看一下傳給他的參數(shù)是什么?

我們留意到,那句調用是這樣子的, /* register the driver, return usb_register return code if error */ retval = usb_register(&usb_storage_driver); 是的,傳遞了一個叫做usb_storage_driver的家伙,這是什么?同一文件中,drivers/usb/storage/usb.c:

struct usb_driver usb_storage_driver = { .owner = THIS_MODULE, .name = "usb-storage", .probe = storage_probe, .disconnect = storage_disconnect, .id_table = storage_usb_ids, }; 可以看到這里定義了一個struct usb_driver的結構體變量,usb_storage_driver,關于usb_driver我們上節(jié)已經(jīng)說過了,當時主要說的是其中的成員driver,而眼下要講的則是另外幾個成員.首先,.owner

和.name這兩個沒啥好多說的,owner這玩藝是用來給模塊計數(shù)的,每個模塊都這么用,賦值總是THIS_MODULE,而name就是這個模塊的名字,usb core會處理它,所以假如這個模塊正常被加載了的話,使用lsmod命令能看到一個叫做usb-storage的模塊名。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多