日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

ldd随笔(1)-linux设备模型

發(fā)布時間:2023/12/10 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ldd随笔(1)-linux设备模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一下只是個人學習后的理解,可能有很多不對的地方。

要學習linux的設(shè)備驅(qū)動模型,首先必須要知道kobject和kset的概念,下面是kobject在2.6.38的源碼中的實現(xiàn)。

struct kobject {const char *name; //名稱,可能在sysfs中創(chuàng)建對應(yīng)的目錄struct list_head entry; //標準鏈表,用于被kset連接起來struct kobject *parent; //指向父kobject的指針struct kset *kset; //指向所屬的kset的指針struct kobj_type *ktype; //包含的kobj_type, 用指向不同的ktype來表示不同的objectstruct sysfs_dirent *sd; //在sysfs中創(chuàng)建目錄時用到的結(jié)構(gòu)struct kref kref; //引用計數(shù)unsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1; };

kobject里面比較重要的一個是kobj_type結(jié)構(gòu)的指針:

struct kobj_type {void (*release)(struct kobject *kobj); //當此kobj被完全釋放(引用為0)時調(diào)用const struct sysfs_ops *sysfs_ops; //與sysfs相關(guān)的操作struct attribute **default_attrs; //代表了一系列屬性。const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);const void *(*namespace)(struct kobject *kobj); };

kobject中的ktype指向不同的kobj_type可以代表著不同的類型,以及所執(zhí)行的不同操作。kobject可能在sysfs中表現(xiàn)為一個目錄,而它指向的kobj_type中包含的一系列struct attribute則代表著這個目錄下的文件。每一個屬性對應(yīng)了一個文件,可以設(shè)置它的讀寫權(quán)限,名稱(文件名)還有就是當讀或者寫這些文件時,調(diào)用的show和store函數(shù)??梢岳眠@些屬性文件,進行信息的展示和配置的修改等。

kobject只是代表著某個結(jié)點,并不能構(gòu)成特定的結(jié)構(gòu),所以還存在一個kset,使得它們可以構(gòu)成一個樹狀結(jié)構(gòu)。kset的實現(xiàn)如下:

struct kset {struct list_head list; //鏈表頭,用以將下層的kobject串起來spinlock_t list_lock; //鏈表的鎖,只能串行操作struct kobject kobj; //kset包含一個kobjectconst struct kset_uevent_ops *uevent_ops; //為了支持熱插拔所提供的結(jié)構(gòu) };

kset里面包含了一個kobject,而不止是一個指針。所以可以把kset看成是一個kobject的擴展,所有對kobject的操作,都適用與kset(操作其中的kobject,但是內(nèi)核為kobject和kset分別提供了一套類似的操作)。如果用C++表述,kobject就是一個基類,而kset是它的派生類。kset可以通過它的list包含住很多子kobject,而這些子kobject又可以通過parent和kset指針指向它的父kobject(kset);并且kset也是(包含了)一個kobject,所以它還可以被其它的kset當做子kobject。這樣就構(gòu)成了一個樹狀結(jié)構(gòu),其中kobject是葉子結(jié)點,而kset是非葉子結(jié)點或者根結(jié)點,正好和目錄與文件的關(guān)系類似。目錄本身是一個文件,但是它可以包含其它文件或目錄,同時又被其它目錄含(根目錄除外)。所以sysfs中的文件結(jié)構(gòu)通常對應(yīng)了內(nèi)核中的kobject結(jié)構(gòu)。每一個目錄代表一個kobject(或者kset),而此目錄里面的子目錄又代表了這個kobject下面的子kobject,目錄里的文件代表了kobject的一系列屬性。

而kset_uevent_ops(對應(yīng)老版內(nèi)核中的hotplug,熱插拔)指向了一組操作,包括過濾,熱插拔等,當往一個kset中添加新的kobject時,便會觸發(fā)這些操作,首先會調(diào)用filter表示是否過濾這個事件,然后在調(diào)用熱插拔處理函數(shù)來向環(huán)境變量里添加值,從而達到通知用戶空間的目的。假如次kset沒有設(shè)置這個uevent_ops指針,便會往它的父kobject迭代查找,直到找到為止(若到根kobject都沒有,就忽略)。再進行調(diào)用。

kobject通常不單獨使用,而是嵌入到其他結(jié)構(gòu),代表就是pci core和usb core,它們是內(nèi)核提供的,利用kobject來構(gòu)造的樹狀結(jié)構(gòu)驅(qū)動框架。

linux內(nèi)核利用以上的框架,包裝出了三個概念,那就是總線,設(shè)備,和驅(qū)動??偩€可以看成是樹狀結(jié)構(gòu)中的非葉子結(jié)點(包括根結(jié)點),設(shè)備和驅(qū)動可以看成其中的葉子結(jié)點;當有設(shè)備插入,便可利用上面uevent_ops的機制,添加環(huán)境變量,然后調(diào)用udev(hotplug)來判斷插入設(shè)備的類型,然后根據(jù)類型查找modules.***map表,找到合適的驅(qū)動程序,加載其入內(nèi)核;當驅(qū)動程序加載到內(nèi)核的時候,同樣會想總線注冊,也會激活uevent_ops的操作,這時系統(tǒng)會對設(shè)備和驅(qū)動進行匹配,若匹配正確,就會調(diào)用驅(qū)動程序里的probe函數(shù)。當設(shè)備取下時,系統(tǒng)會調(diào)用驅(qū)動程序的remove函數(shù)。這樣就可以支持熱插拔。

linux內(nèi)核還提供了usb和pci等總線的抽象,它們是在bus,device和driver之上進行進一步的包裝。內(nèi)核已經(jīng)把總線和設(shè)備的部分完成了,驅(qū)動作者只需要關(guān)注驅(qū)動程序的實現(xiàn)即可。例如,linux內(nèi)核提供的usb core已經(jīng)完成了usb的大部分工作,包括總線驅(qū)動,以及usb框架,還有設(shè)備的識別和初始化等,以及設(shè)備和驅(qū)動之間進行通信的urb方式,甚至還包含了大部分設(shè)備的驅(qū)動程序,但是有的設(shè)備驅(qū)動內(nèi)核并沒有。我們會在windows經(jīng)常看到一種情況,某個設(shè)備被識別了,但是沒有驅(qū)動程序而不能被使用,其中識別出設(shè)備就是內(nèi)核所完成的,而這樣的驅(qū)動往往就必須由設(shè)備提供者自己實現(xiàn)了??傊趦?nèi)核抽象出一套驅(qū)動框架之上,驅(qū)動作者可以免去很多的工作。

轉(zhuǎn)載于:https://www.cnblogs.com/xien7/archive/2013/02/03/2890577.html

總結(jié)

以上是生活随笔為你收集整理的ldd随笔(1)-linux设备模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。