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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux中THIS_MODULE宏定义详解

發(fā)布時間:2024/1/17 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux中THIS_MODULE宏定义详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ?一直都在耿耿于懷,這個THIS_MODULE到底是個什么玩意,linux內(nèi)核中無處不在的東西。今天上網(wǎng)搜了一下,算是基本明白了。網(wǎng)上牛人寫的已經(jīng)比較詳細,另外目前暫時沒有時間往更深層次分析,所以直接貼過來得了。。。

轉(zhuǎn)帖網(wǎng)址:

http://blog.csdn.net/a954423389/archive/2010/12/27/6101369.aspx

源碼位置:

@ kernel/module.c

@ include/linux/module.h

?

結(jié)構(gòu)體struct module在內(nèi)核中代表一個內(nèi)核模塊,通過insmod(實際執(zhí)行init_module系統(tǒng)調(diào)用)把自己編寫的內(nèi)核模塊插入內(nèi)核時,模塊便與一個?struct module結(jié)構(gòu)體相關(guān)聯(lián),并成為內(nèi)核的一部分。下面是結(jié)構(gòu)體struct module的完整定義,接下來會逐個解釋:

????struct module

????{

????????enum module_state state;

????????struct list_head list;

????????char name[MODULE_NAME_LEN];

?

????????struct module_kobject mkobj;

????????struct module_param_attrs *param_attrs;

????????const char *version;

????????const char *srcversion;

?

????????const struct kernel_symbol *syms;

????????unsigned int num_syms;

????????const unsigned long *crcs;

?

????????const struct kernel_symbol *gpl_syms;

????????unsigned int num_gpl_syms;

????????const unsigned long *gpl_crcs;

?

????????unsigned int num_exentries;

????????const struct exception_table_entry *extable;

?

????????int (*init)(void);

????????void *module_init;

????????void *module_core;

????????unsigned long init_size, core_size;

????????unsigned long init_text_size, core_text_size;

????????struct mod_arch_specific arch;

????????int unsafe;

????????int license_gplok;

?

#ifdef CONFIG_MODULE_UNLOAD

????????struct module_ref ref[NR_CPUS];

????????struct list_head modules_which_use_me;

????????struct task_struct *waiter;

????????void (*exit)(void);

#endif

?

#ifdef CONFIG_KALLSYMS

????????Elf_Sym *symtab;

????????unsigned long num_symtab;

????????char *strtab;

????????struct module_sect_attrs *sect_attrs;

#endif

????????void *percpu;

????????char *args;

????};

????我們插入一個內(nèi)核模塊,一般會使用工具insmod,該工具實際上調(diào)用了系統(tǒng)調(diào)用init_module,在該系統(tǒng)調(diào)用函數(shù)中,首先調(diào)用?load_module,把用戶空間傳入的整個內(nèi)核模塊文件創(chuàng)建成一個內(nèi)核模塊,返回一個struct module結(jié)構(gòu)體。內(nèi)核中便以這個結(jié)構(gòu)體代表這個內(nèi)核模塊。

????state是模塊當(dāng)前的狀態(tài)。它是一個枚舉型變量,可取的值為:MODULE_STATE_LIVE,MODULE_STATE_COMING,MODULE_STATE_GOING。分別表示模塊當(dāng)前正常使用中(存活狀態(tài)),模塊當(dāng)前正在被加載,模塊當(dāng)前正在被卸載。load_module函數(shù)中完成模塊的部分創(chuàng)建工作后,把狀態(tài)置為MODULE_STATE_COMING,sys_init_module函數(shù)中完成模塊的全部初始化工作后(包括把模塊加入全局的模塊列表,調(diào)用模塊本身的初始化函數(shù)),把模塊狀態(tài)置為MODULE_STATE_LIVE,最后,使用rmmod工具卸載模塊時,會調(diào)用系統(tǒng)調(diào)用delete_module,會把模塊的狀態(tài)置為MODULE_STATE_GOING。這是模塊內(nèi)部維護的一個狀態(tài)。

????list是作為一個列表的成員,所有的內(nèi)核模塊都被維護在一個全局鏈表中,鏈表頭是一個全局變量struct module *modules。任何一個新創(chuàng)建的模塊,都會被加入到這個鏈表的頭部,通過modules->next即可引用到。

????name是模塊的名字,一般會拿模塊文件的文件名作為模塊名。它是這個模塊的一個標(biāo)識。

????另外,還要介紹一下宏THIS_MODULE,它的定義如下是#define THIS_MODULE (&__this_module),__this_module是一個struct module變量,代表當(dāng)前模塊,跟current有幾分相似。可以通過THIS_MODULE宏來引用模塊的struct module結(jié)構(gòu),試試下面的模塊:

????#include <linux/module.h>

?

????MODULE_LICENSE("Dual BSD/GPL");

?

????static int hello_init(void)

????{

????????unsigned int cpu = get_cpu();

????????struct module *mod;

????????printk(KERN_ALERT "this module: %p==%p/n", &__this_module, THIS_MODULE );

????????printk(KERN_ALERT "module state: %d/n", THIS_MODULE->state );

????????printk(KERN_ALERT "module name: %s/n", THIS_MODULE->name );

????????list_for_each_entry(mod, *(&THIS_MODULE->list.prev), list )

????????????????printk(KERN_ALERT "module name: %s/n", mod->name );

????????return 0;

????}

?

????static void hello_exit(void)

????{

????????printk(KERN_ALERT "module state: %d/n", THIS_MODULE->state );

????}

?

????module_init(hello_init);

????module_exit(hello_exit);

?

owner是一個struct module *類型的結(jié)構(gòu)體指針,現(xiàn)在告訴你的是每個struct module結(jié)構(gòu)體在內(nèi)核里都代表了一個內(nèi)核模塊,就像十七大里的每個代表都代表了一批人,至于代表了什么人,選他們的人才知道,同樣,每個struct module結(jié)構(gòu)體代表了什么模塊,對它進行初始化的模塊才知道。當(dāng)然,初始化這個結(jié)構(gòu)不是寫驅(qū)動的人該做的事,是在剛才略過的那個從insmod或?modprobe到你驅(qū)動的xxx_init函數(shù)的曲折過程中做的事。insmod命令執(zhí)行后,會調(diào)用kernel/module.c里的一個系統(tǒng)調(diào)用init_module,它會調(diào)用load_module函數(shù),將用戶空間傳入的整個內(nèi)核模塊文件創(chuàng)建成一個內(nèi)核模塊,并返回一個struct module結(jié)構(gòu)體,從此,內(nèi)核中便以這個結(jié)構(gòu)體代表這個內(nèi)核模塊。

再看看THIS_MODULE宏是什么意思,它在include/linux/module.h里的定義是

85 #define THIS_MODULE (&__this_module)

??? 是一個struct module變量,代表當(dāng)前模塊,與那個著名的current有幾分相似,可以通過THIS_MODULE宏來引用模塊的struct module結(jié)構(gòu),比如使用THIS_MODULE->state可以獲得當(dāng)前模塊的狀態(tài)。現(xiàn)在你應(yīng)該明白為啥在那個歲月里,你需要毫不猶豫毫不遲疑的將struct usb_driver結(jié)構(gòu)里的owner設(shè)置為THIS_MODULE了吧,這個owner指針指向的就是你的模塊自己。那現(xiàn)在owner咋就說沒就沒了那?這個說來可就話長了,咱就長話短說吧。不知道那個時候你有沒有忘記過初始化owner,反正是很多人都會忘記,大家都把注意力集中到probe、?disconnect等等需要動腦子的角色上面了,這個不需要動腦子,只需要花個幾秒鐘指定一下的owner反倒常常被忽視,這個就是容易得到的往往不去珍惜,不容易得到的往往日日思量著去爭取。于是在2006年的春節(jié)前夕,在咱們都無心工作無心學(xué)習(xí)等著過春節(jié)的時候,Greg堅守一線,去掉了?owner,于是千千萬萬個寫usb驅(qū)動的人再也不用去時刻謹記初始化owner了。咱們是不用設(shè)置owner了,可core里不能不設(shè)置,struct usb_driver結(jié)構(gòu)里不是沒有owner了么,可它里面嵌的那個struct device_driver結(jié)構(gòu)里還有啊,設(shè)置了它就可以了。于是Greg同時又增加了usb_register_driver()這么一層,usb_register()可以通過將參數(shù)指定為THIS_MODULE去調(diào)用它,所有的事情都挪到它里面去做。反正usb_register()?也是內(nèi)聯(lián)的,并不會增加調(diào)用的開銷。

?

?

其余相關(guān)網(wǎng)址,可供參考:

http://hi.baidu.com/_huangshuijing/blog/item/253f9a9516183f0c7bf480c5.html

?

http://www.embedu.org/Column/Column92.htm

?

以下均針對于內(nèi)核2.6.18

在module.h 中 THIS_MODULE的定義如下:

extern struct module __this_module; #define THIS_MODULE (&__this_module)

即是保存了__this_module這個對象的地址,那這個__this_module在哪里定義呢?這就要從module的編譯說起啦,如果編譯過模塊就會發(fā)現(xiàn),會生成*.mod.c這樣的一個文件,打開這個文件,就會發(fā)現(xiàn),類似下面的定義:

struct module __this_module __attribute__((section(".gnu.linkonce.this_module"))) = {.name = KBUILD_MODNAME,.init = init_module, #ifdef CONFIG_MODULE_UNLOAD.exit = cleanup_module, #endif };

這個文件是調(diào)用modpost生成的,modpost的main中有這樣一段代碼:

for (mod = modules; mod; mod = mod->next) {if (mod->skip)continue;buf.pos = 0;add_header(&buf, mod);add_versions(&buf, mod);add_depends(&buf, mod, modules);add_moddevtable(&buf, mod);add_srcversion(&buf, mod);sprintf(fname, "%s.mod.c", mod->name);write_if_changed(&buf, fname);}

其中的add_header就偷偷添加了__this_module 的定義

static void add_header(struct buffer *b, struct module *mod) {buf_printf(b, "#include <linux/module.h>\n");buf_printf(b, "#include <linux/vermagic.h>\n");buf_printf(b, "#include <linux/compiler.h>\n");buf_printf(b, "\n");buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");buf_printf(b, "\n");buf_printf(b, "struct module __this_module\n");buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");buf_printf(b, " .name = KBUILD_MODNAME,\n");if (mod->has_init)buf_printf(b, " .init = init_module,\n");if (mod->has_cleanup)buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"" .exit = cleanup_module,\n""#endif\n");buf_printf(b, "};\n"); }

?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Linux中THIS_MODULE宏定义详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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