在新版本的內核中struct device 已經沒有bus_id成員,取而代之的是經過dev_name和dev_set_name對設備的名字進行操做。
dev_name和dev_set_name在2.6.35.6內核中的源代碼以下:
static inline const char *dev_name(const struct device *dev)
{
/* Use the init name until the kobject becomes available */
if (dev->init_name)
return dev->init_name;
return kobject_name(&dev->kobj);
}
extern int dev_set_name(struct device *dev, const char *name, ...)
__attribute__((format(printf, 2, 3)));
kernel 郵件列表
中講了:struct device - replace bus_id with dev_name(),之後只要使用dev->bus_id的時候,改爲dev_name(dev)就能夠了。
第四章:linux內核模塊:
4.5,模塊被加載後,在/sys/module/目錄下將出現以此模塊名命名的目錄。當「參數讀/寫權限」爲 0 時,表示此參數不存在 sysfs 文件系統下對應的文件節點,若是此模塊存在「參數讀/寫權限」不爲 0的命令行參數,在此模塊的目錄下還將出現 parameters目錄,包含一系列以參數名命名的文件節點,這些文件的權限值就是傳入module_param()的「參數讀/寫權限」 ,而文件的內容爲參數的值。
4.6,導出符號:
模塊可使用以下宏導出符號到內核符號表:
EXPORT_SYMBOL(符號名);
EXPORT_SYMBOL_GPL(符號名);
導 出的 符號 將可 以 被 其 他 模塊 使用 , 使用 前 聲明 一 下 即 可 。
4.8,模塊的使用計數
Linux 2.6 內核提供了模塊計數管理接口 try_module_get(&module)和 module_put(&module),
int try_module_get(struct module *module);
該函數用於增長模塊使用計數;若返回爲 0,表示調用失敗,但願使用的模塊沒有被加載或正在被卸載中。
void module_put(struct module *module);
該函數用於減小模塊使用計數。
第 5 章 Linux文件系統與設備文件系統
1.file結構體
文件結構體表明一個打開的文件(設備對應於設備文件) ,系統中每一個打開的文件在內核空間都有一個關聯的 struct file。它由內核在打開文件時建立,並傳遞給在文件上進行操做的任何函數。在文件的全部實例都關閉後,內核釋放這個數據結構。在內核和驅動源代碼中,struct file的指針一般被命名爲 file 或 filp(即 file pointer)。代碼清單 5.3給出了文件結構體的定義。
2.inode結構體
VFS inode 包含文件訪問權限、屬主、組、大小、生成時間、訪問時間、最後修改時間等信息。它是Linux 管理文件系統的最基本單位,也是文件系統鏈接任何子目錄、文件的橋樑,inode結構體的定義如代碼清單5.4所示。
5.4.1 udev與devfs的區別
取代 devfs的幾點緣由:
1.devfs所作的工做被確信能夠在用戶態來完成。
2.一些bug至關長的時間內未被修復。
3.devfs的維護者和做者中止了對代碼的維護工做。
udev 徹底在用戶態工做,利用設備加入或移除時內核所發送的熱插拔事件(hotplug event)來工做。在熱插拔時,設備的詳細信息會由內核輸出到位於/sys的sysfs文件系統。udev的設備命名策略、權限控制和事件處理都是在用戶態下完成的,它利用sysfs中的信息來進行建立設備文件節點等工做。
5.4.2 sysfs文件系統與Linux設備模型
1.sysfs 文件系統
sysfs把鏈接在系統上的設備和總線組織成爲一個分級的文件, 它們能夠由用戶空間存取,向用戶空間導出內核數據結構以及它們的屬性。sysfs的一個目的就是展現設備驅動模型中各組件的層次關係,其頂級目錄包括block、device、bus、drivers、class、power 和 firmware。
2.kobject內核對象
kobject是Linux 2.6 引入的設備管理機制,在內核中由kobject結構體表示,這個數據結構使全部設備在底層都具備統一的接口。kobject提供了基本的對象管理能力,是構成 Linux 2.6 設備模型的核心結構,每一個在內核中註冊的 kobject 對象都對應於sysfs文件系統中的一個目錄。
kobject結構體的定義如代碼清單 5.6所示。
1 struct kobject
2 {
3 char *k_name;
4 char name[KOBJ_NAME_LEN]; //對象名稱
5 struct kref kref; //對象引用計數
6 struct list_head entry; //用於掛接該kobject對象到kset鏈表
7 struct kobject *parent; //指向父對象的指針
8 struct kset *kset; //所屬kset的指針
9 struct kobj_type *ktype; //指向對象類型描述符的指針
10 struct dentry *dentry; //sysfs文件系統中與該對象對應的文件節點入口
11 };
內核經過 kobject 的 kref 成員實現對象引用計數管理,且提供兩個函數kobject_get()、kobject_put()分別用於增長和減小引用計數;
kobj_type 數據結構包含 3 個成員:用於釋放 kobject 佔用的資源的release()函數、指向sysfs操做的 sysfs_ops指針和sysfs文件系統默認屬性列表。
1 struct kobj_type
2 {
3 void (*release)(struct kobject *);//release函數
4 struct sysfs_ops * sysfs_ops;//屬性操做
5 struct attribute ** default_attrs;//默認屬性
6 };
kobj_type 結構體種的 sysfs_ops 包括 store()和 show()兩個成員函數,用於實現屬性的讀寫;
Linux內核中提供一系列操做kobject的函數:
void kobject_init(struct kobject * kobj);
該函數用於初始化 kobject,它設置kobject引用計數爲1,entry域指向自身,其所屬 kset引用計數加1。
int kobject_set_name(struct kobject *kobj, const char *format, ...);
該函數用於設置指定kobject的名稱。
void kobject_cleanup(struct kobject * kobj) 和 void kobject_release(struct kref *kref);
該函數用於清除kobject,當其引用計數爲0時,釋放對象佔用的資源。
struct kobject *kobject_get(struct kobject *kobj);
該函數用於將kobj 對象的引用計數加1,同時返回該對象的指針。
void kobject_put(struct kobject * kobj);
該函數用於將 kobj 對象的引用計數減 1,若是引用計數降爲 0,則調用
kobject_release()釋放該 kobject對象。
int kobject_add(struct kobject * kobj);
該函數用於將 kobject 對象加入 Linux 設備層次,它會掛接該 kobject 對象到 kset的 list鏈中,增長父目錄各級kobject的引用計數,在其parent指向的目錄下建立文件節點,並啓動該類型內核對象的hotplug函數。
int kobject_register(struct kobject * kobj);
該函數用於註冊kobject, 它會先調用kobject_init()初始化kobj, 再調用kobject_add()完成該內核對象的添加。
void kobject_del(struct kobject * kobj);
這個函數是kobject_add()的反函數, 它從Linux設備層次(hierarchy)中刪除 kobject對象。
void kobject_unregister(struct kobject * kobj);
這個函數是 kobject_register()的反函數,用於註銷 kobject。與 kobject_register()相反,它首先調用kobject_del()從設備層次中刪除該對象,再調用 kobject_put()減小該對象的引用計數,若是引用計數降爲0,則釋放該kobject對象。