linux 2 6核心模組引用計數的實現

2021-08-23 15:53:11 字數 3285 閱讀 9258

一、模組使用計數的背景知識

模組是一種可以在核心執行過程中動態載入、解除安裝的核心功能元件。2.6核心中模組的

命名方式為*.ko。模組在被使用時,是不允許被解除安裝的。程式設計時需要用「使用計數」來描述模組是否在被使用。

二、2.4核心使用計數的實現方法

2.4核心中,模組自身通過mod_inc_use_count, mod_dec_use_count巨集來管理自己被使用的計數。通常我們在寫模組時,會在open方法中加入mod_inc_use_count,在close方法中加入mod_dec_use_count來實現使用計數。

三、2.6核心使用計數的實現方法

2.6核心提供了更健壯、靈活的模組計數管理介面try_module_get(&module), module_put(&module)取代2.4中的模組使用計數管理巨集。模組的使用計數不必由自身管理,而且在管理模組使用計數時考慮到smp與preempt機制的影響(參考module.h中try_module_get和module.c中module_put的實現)。

int try_module_get(struct module *module);

用於增加模組使用計數;若返回為0,表示呼叫失敗,希望使用的模組沒有被載入或正在被解除安裝中。

void module_put(struct module *module);

減少模組使用計數。

try_module_get

與module_put 的引入與使用與2.6核心下的裝置模型密切相關。2.6核心為不同型別的裝置定義了struct module *owner 域,用來指向管理此裝置的模組。如字元裝置的定義:

struct cdev

;struct file_operations ;

從裝置使用的角度出發,當需要開啟、開始使用某個裝置時,使用try_module_get(dev->owner)去增加管理此裝置的owner模組的使用計數;當關閉、不再使用此裝置時,使用module_put(dev->owner)減少對管理此裝置的owner模組的使用計數。這樣,當裝置在使用時,管理此裝置的模組就不能被解除安裝;只有裝置不再使用時模組才能被解除安裝。

2.6核心下,對於為具體裝置寫驅動的開發人員而言,基本無需使用try_module_get與module_put,因為此時開發人員所寫的驅動通常為支援某具體裝置的owner模組,對此裝置owner模組的計數管理由核心裡更底層的**如匯流排驅動或是此類裝置共用的核心模組來實現,從而簡化了裝置驅動開發。

四、舉例說明2.6核心模組使用計數的實現過程

舉乙個2.6核心下字元裝置驅動編寫的例子來說明問題。在2.6核心下編寫乙個裝置驅動時,初始化過程中大家都會看到如下的模板:

static struct file_operations ******_remap_ops = ;

static void ******_setup_cdev(struct cdev *dev, int minor,

struct file_operations *fops)

無論是cdev還是file_operations都將自己的struct module *owner成員指向了this_module。那麼這個this_module是什麼呢?

核心原始碼目錄下include/linux/module.h

#ifdef module

#define module_generic_table(gtype,name) \

extern const struct gtype##_id __mod_##gtype##_table \

__attribute__ ((unused, alias(__stringify(name))))

extern struct module__this_module;

#define this_module (&__this_module)

#else /* !module */

#define module_generic_table(gtype,name)

#define this_module ((struct module *)0)

#endif

__this_module這個符號是在載入到核心後才產生的。insmod命令執行後,會呼叫kernel/module.c裡的乙個系統呼叫sys_init_module,它會呼叫load_module函式,將使用者空間傳入的整個核心模組檔案建立成乙個核心模組,並返回乙個struct module結構體,從此,核心中便以這個結構體代表這個核心模組。this_module類似程序的current。

struct module

struct module_ref

____cacheline_aligned;

現在咱們就看看核心是如何幫助我們完成使用計數的。

在2.4核心中,我們是通過在open方法中增加引用計數,在close方法中減少引用計數。在2.6內

核中,核心肯定也是要在open、close時幫助我們實現同樣功能的。

l開啟字元裝置的大體流程如下:

sys_open()->do_sys_open()->

do_filp_open()->nameidata_to_filp() ->__dentry_open()->chrdev_open()->open()

2.6核心中並不要求模組在open中顯示的實現使用計數,真正使用模組使用計數是在chrdev_open()

中完成的。

核心原始碼fs/char_dev.c

static int chrdev_open(struct inode *inode, struct file *filp)

// 增加file_operations中owner

指向的module

的使用計數

if (filp->f_op->open) }

static struct kobject *cdev_get(struct cdev *p)

核心原始碼include/linux/fs.h

#define fops_get(fops) \

(((fops) && try_module_get((fops)->owner) ? (fops) : null)) l

關閉裝置的大體流程

sys_close()->filp_close()->fput()->__fput()->release()

2.6核心中並不要求模組在release中顯示的實現使用計數,真正使用模組使用計數是在__fput()

中完成的。

void __fput(struct file *file)

linux 2 6核心模組引用計數的實現

劉洪濤,華清遠見嵌入式學院 金牌講師。一 模組使用計數的背景知識 模組是一種可以在核心執行過程中動態載入 解除安裝的核心功能元件。2.6核心中模組的命名方式為 ko。模組在被使用時,是不允許被解除安裝的。程式設計時需要用 使用計數 來描述模組是否在被使用。二 2.4核心使用計數的實現方法 2.4核心...

linux 2 6核心模組引用計數的實現 zz

linux 2.6核心模組引用計數的實現 劉洪濤,華清遠見嵌入式學院金牌講師。一 模組使用計數的背景知識 模組是一種可以在核心執行過程中動態載入 解除安裝的核心功能元件。2.6核心中模組的命名方式為 ko。模組在被使用時,是不允許被解除安裝的。程式設計時需要用 使用計數 來描述模組是否在被使用。二 ...

linux 2 6 核心模組程式設計探索

乙個linux 核心模組程式設計的手記,未寫完不斷更新中 一 相關命令 0 檢視系統裝載了哪些 核心模組 lsmod modulename 1 載入核心模組 insmod modulename 2 解除安裝核心模組 rmmod modulename 3 建立裝置檔案 mknod filename d...