linux核心對象管理
核心中很多地方都需要跟蹤記錄C語言中結構的執行個體。盡管這些對象的用法大不相同,但各個子系統的某些操作都非常類似,如引用計數,核心為了減少代碼複制,采用了一般性的方法來管理核心對象。所引入的架構并不隻是為了減少代碼複制,同時也為核心不同部分管理的對象提供了一緻的視圖。
一般性的核心對象機制可用于執行下列對象操作:
1. 引用計數;
2. 管理對象連結清單;
3. 集合加鎖;
4. 将對象屬性導出到使用者空間(通過sysfs檔案系統);
一般性的核心對象kobject
struct kobject {
const char * k_name; // 對象的文本名稱
char name[KOBJ_NAME_LEN];
struct kref kref; // 引用計數的管理
struct list_head entry; // 連結多個kobject
struct kobject * parent; //指向父對象的指針,用于在kobject之間建立層次結構
struct kset * kset; // 對象所屬的集合
struct kobj_type * ktype; // 包含kobject資料結構的更多詳細資訊
struct dentry * dentry;
wait_queue_head_t poll;
};
kobject資料結構嵌入到其它結構中,用作核心對象的基礎。通過管理kobjcet即達到了對包含kobject的對象的管理。
核心提供了處理kobject的一套标準方法,包括:
kobject_get, kobject_put | 對kobject的引用計數器加1或減1 |
kobject_(un)register | 注冊或删除對象,對象被添加到父對象現存的集合中,同時在sysfs中建立一個對應項 |
kobjcet_init | 初始化kobject對象 |
kobject_add | 初始化核心對象,并使之顯示在sysfs中 |
kobject_cleanup | 在不需要kobject(以及包含kobjcet的對象)時,釋放配置設定的資源 |
在很多情況下,必須将不同的核心對象歸類到集合中(相同類型的對象擁有公共的kobj_type),例如所有字元裝置集合,或所有基于PCI的裝置集合,核心通過kset完成這一目标。
struct kset {
struct subsystem * subsys;
struct kobj_type * ktype; // ktype指向kset中各個核心對象公用的kobj_type結構
struct list_head list; // 同類型對象連結清單
spinlock_t list_lock;
struct kobject kobj; // 管理kset對象本身的内嵌kobject對象
struct kset_uevent_ops * uevent_ops;
};
kset是核心對象應用的第一個例子,kset中内嵌kobject結構,用于管理kset對象本身,與集合中包含的各個kobject對象并無關系。
引用計數用于檢測核心中有多少個地方使用了某個對象。每當核心的一個部分需要某個對象所包含的資訊時,則增加該對象的引用計數;如果不再需要相應的資訊,則減少該對象的引用計數,當對象的引用計數為0時,核心知道不在需要該對象。
核心通過kref結構來管理引用計數
struct kref {
atomic_t refcount;
};
在kref的設計中,将一個值封裝在結構中,防止直接操縱該值,需使用輔助方法kref_init(初始化), kref_get(加1), kref_put(減1)進行操作。
