Linux驅動程序中THIS_MODULE 的定義
結構體struct module在內核中代表一個內核模塊,通過insmod(實際執(zhí)行init_module系統(tǒng)調用)把自己編寫的內核模塊插入內核時,模塊便與一個struct module結構體相關聯(lián),并成為內核的一部分。下面是結構體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; }; |
我們插入一個內核模塊,一般會使用工具insmod,該工具實際上調用了系統(tǒng)調用init_module,在該系統(tǒng)調用函數(shù)中,首先調用load_module,把用戶空間傳入的整個內核模塊文件創(chuàng)建成一個內核模塊,返回一個struct module結構體。內核中便以這個結構體代表這個內核模塊。
state是模塊當前的狀態(tài)。它是一個枚舉型變量,可取的值為:MODULE_STATE_LIVE,MODULE_STATE_COMING,MODULE_STATE_GOING。分別表示模塊當前正常使用中(存活狀態(tài)),模塊當前正在被加載,模塊當前正在被卸載。load_module函數(shù)中完成模塊的部分創(chuàng)建工作后,把狀態(tài)置為MODULE_STATE_COMING,sys_init_module函數(shù)中完成模塊的全部初始化工作后(包括把模塊加入全局的模塊列表,調用模塊本身的初始化函數(shù)),把模塊狀態(tài)置為MODULE_STATE_LIVE,最后,使用rmmod工具卸載模塊時,會調用系統(tǒng)調用delete_module,會把模塊的狀態(tài)置為MODULE_STATE_GOING。這是模塊內部維護的一個狀態(tài)。
list是作為一個列表的成員,所有的內核模塊都被維護在一個全局鏈表中,鏈表頭是一個全局變量struct module *modules。任何一個新創(chuàng)建的模塊,都會被加入到這個鏈表的頭部,通過modules->next即可引用到。
name是模塊的名字,一般會拿模塊文件的文件名作為模塊名。它是這個模塊的一個標識。
另外,還要介紹一下宏THIS_MODULE,它的定義如下是#define THIS_MODULE (&__this_module),__this_module是一個struct module變量,代表當前模塊,跟current有幾分相似??梢酝ㄟ^THIS_MODULE宏來引用模塊的struct module結構,試試下面的模塊:
#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); |
posted on 2014-03-04 10:20 順其自然EVO 閱讀(1543) 評論(0) 編輯 收藏 所屬分類: linux