linux驅動結構

2021-07-05 10:15:40 字數 4225 閱讀 3775

kobject 

->kobject *parent 

->kset

->struct list_head    //指向了所包含的kobject的煉表頭

->struct kobject kobj    

->kobj_type

->void (*release) (struct kobject *kobj)

->struct sysfs_ops *sysfs_ops;

....

(1).kobject如果沒有指定父節點,parent將指向kset內嵌的kobject。

(2)每個kobject都有它的kobj_type欄位指標,用來表示kobject在檔案系統中

的操作方法。relase方法是在kobject釋放時呼叫,sysfs_ops指向kobject

對應的檔案操作,default_attrskobject的預設屬性,sysfs_ops將使用這

個屬性。

一、kobject在核心的結構:

(1)kobject_create_and_add()函式建立kobject,掛到父kobject,並設定其kobj_type,在檔案系統中為其建立目錄和屬性檔案等。

kobject_create_and_add()

->kobject_create()

->kobject_init()

->kobject_init_internal()

->kobject_add()

->kobject_add_varg()

->kobject_set_name_vargs(kobj, fmt, vargs)

->kvasprintf()

->kobject_add_internal()

->kobject_get(kobj->parent);

->create_dir(kobj)

->sysfs_create_dir(kobj);

->populate_dir(kobj)

->sysfs_remove_dir(kobj)

函式說明:

kobject_create_and_add()介面函式,kobject新增到檔案系統中去(實際上是新增到其父節點所代表的kset中去)

kobject_create()為要建立的kobject分配記憶體空間並對其初始化.

kobject_init()對kobject基本字段進行初始化,用輸入引數設定kobj_type屬性.

kobject_add_varg中將把fmt指向的內容賦給kobject的name欄位。 

kobject_set_name_vargs(kobj, fmt, vargs),如果kobj的name欄位指向的內容為空,則為分配乙個記憶體空

間並用fmt指向的內容初始化,把位址賦給kobj的name欄位。   

kobject_add_varg()返回kobject_add_internal(kobj),就是在這個函式理為kobj建立檔案系統結構

kobject_add_internal()檢查kobj和它的name欄位,不存在則返回錯誤資訊

arent = kobject_get(kobj->parent);獲得其父節點,並增加父節點的計數器,kobject結構中的

kref欄位用於容器的計數,kobject_get和kobject_put分別

增加和減少計數器,如果計數器為0,則釋放該kobject,

kobject_get返回該kobject。

create_dir()函式中具體建立了那些內容

sysfs_create_dir()先為kobj建立了乙個目錄檔案

如果kobj->parent為null,就把&sysfs_root作為父節點sd,即在/sys下面建立結

點。populate_dir:然後呼叫

由於上面kobject_init(kobj, &dynamic_kobj_ktype)用預設dynamic_kobj_ktype作為kobj_type引數,而dynamic_kobj_ktype的default_attrs為null,所以這裡沒有建立屬性檔案。

至此,我們已經知道了kobject_create_and_add()函式建立kobject,掛到父kobject,並設定其kobj_type,在檔案系統中為其建立目錄和屬性檔案等。

另外,如果我們已靜態定義了要建立的kobject,則可以呼叫kobject_init_and_add()來註冊kobject

int kobject_init_and_add()

(2)我們已靜態定義了要建立的kobject,則可以呼叫kobject_init_and_add()來註冊kobject

(3)核心提供登出kobject的函式是kobject_del()

二、kset在核心中的結構:

(1)核心同樣提供了建立和註冊kset的函式kset_create_and_add()

->先呼叫kset_create ()建立乙個kset,接著呼叫kset_register()註冊它

->kset_create()中kset內嵌的kobject(這裡還未將kobject註冊到檔案系統),另外用輸

入引數初始化kset的uevent_ops欄位。

->kset_register()呼叫kobject_add_internal()將kset內嵌的kobject註冊到檔案系統,                 這個函式我們在上面已經分析。

->註冊kset會產生乙個事件,就是在這裡呼叫了kobject_uevent(&k->kobj,                                kobj_add)

->如果kobj的kset和parent欄位都不存在,說明找不到所屬kset,也就沒有                                uevent_ops,不能產生事件,返回錯誤資訊;相反則找到了存在kset的kobj                              或父kobject(依次往上找),並賦值給uevent_ops。

->add_uevent_var()kobj_uevent_env填充action_string,kobject路徑,

子系統名稱以及其他指定環境變數

->呼叫uevent_ops的uevent函式,程式設計人員可在此函式中實現自定義的

功能。->設定kobj_add和kobj_remove的標誌。

->新增home和path環境變數。

->呼叫hotplug函式。

(2)kset_unregister() 減少其內嵌的kobj計數,為0則釋放其記憶體空間。

常用函式:

1 #define mkdev(major,minor) (((major) << minorbits) | (minor))  將主裝置號和次裝置號轉換成

dev_t型別

2 struct list_head ;

#define list_head_init(name)  

->list_head() 

#define list_head(name) \

struct list_head name = list_head_init(name)

static inline void init_list_head(struct list_head *list)

常見函式:

cdev_alloc(void)

-> kzalloc(sizeof(struct cdev), gfp_kernel)

->init_list_head(&p->list)

->kobject_init(&p->kobj, &ktype_cdev_dynamic)

cdev_init(...)

->init_list_head(&cdev->list)

->kobject_init(&cdev->kobj, &ktype_cdev_default)

->cdev->ops = fops;

cdev_add(...)

->kobj_map(...)   kobj_map 結構的 cdev_map 變數中包含乙個雜湊表用來快速訪問所有的物件。

kobj_map() 函式就是用來把字元裝置編號和 cdev 結構變數一起保                                     存到 cdev_map 這個雜湊表裡。當後續要開啟乙個字元裝置檔案時,                                    通過呼叫 kobj_lookup() 函式,根據裝置編號就可以找到 cdev 結                                     構變數,從而取出其中的 ops 字段。

驅動 網絡卡驅動 linux核心網路分層結構

preface linux核心對網路驅動程式使用統一的介面,並且對於網路裝置採用物件導向的思想設計。linux核心採用分層結構處理網路資料報。分層結構與網路協議的結構匹配,既能簡化資料報處理流程,又便於擴充套件和維護。核心網路結構 在linux核心中,對網路部分按照網路協議層 網路裝置層 裝置驅動功...

linux驅動結構pci之resource

linux設計了乙個通用的資料結構resource來描述各種i o資源 如 i o埠 外設記憶體 dma和irq等 該結構定義在include linux ioport.h標頭檔案中 struct resource linux是以一種倒置的樹形結構來管理每一類i o資源 如 i o埠 外設記憶體 d...

linux網路驅動體系結構

在分析網絡卡驅動程式之前,我們先來了解一下linux網路驅動體系結構 我們來說一下流程 當網路裝置驅動載入時,首先在入口函式裡面完成一些初始化工作,這主要就是對net device結構體的設定,以及跟硬體相關的設定,其中發包和收包函式比較重要。ifconfig up來配置網絡卡的時候,會呼叫net ...