Linux驅動程序中THIS_MODULE 的定義


本文裝載自:http://blog.163.com/jlz_325/blog/static/191740009201187101038209/

結構體struct module在內核中代表一個內核模塊,通過insmod(實際執行init_module系統調用)把自己編寫的內核模塊插入內核時,模塊便與一個struct module結構體相關聯,併成爲內核的一部分。下面是結構體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,該工具實際上調用了系統調用init_module,在該系統調用函數中,首先調用load_module,把用戶空間傳入的整個內核模塊文件創建成一個內核模塊,返回一個struct module結構體。內核中便以這個結構體代表這個內核模塊。
state是模塊當前的狀態。它是一個枚舉型變量,可取的值爲:MODULE_STATE_LIVE,MODULE_STATE_COMING,MODULE_STATE_GOING。分別表示模塊當前正常使用中(存活狀態),模塊當前正在被加載,模塊當前正在被卸載。load_module函數中完成模塊的部分創建工作後,把狀態置爲MODULE_STATE_COMING,sys_init_module函數中完成模塊的全部初始化工作後(包括把模塊加入全局的模塊列表,調用模塊本身的初始化函數),把模塊狀態置爲MODULE_STATE_LIVE,最後,使用rmmod工具卸載模塊時,會調用系統調用delete_module,會把模塊的狀態置爲MODULE_STATE_GOING。這是模塊內部維護的一個狀態。
list是作爲一個列表的成員,所有的內核模塊都被維護在一個全局鏈表中,鏈表頭是一個全局變量struct module *modules。任何一個新創建的模塊,都會被加入到這個鏈表的頭部,通過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);

發佈了7 篇原創文章 · 獲贊 14 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章