结构体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。
- enum module_state
- {
- MODULE_STATE_LIVE, //模块当前正常使用中(存活状态) 0
- MODULE_STATE_COMING, //模块当前正在被加载 1
- MODULE_STATE_GOING, //模块当前正在被卸载 2
- };
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("GPL");
MODULE_AUTHOR("Jack Chen"); /*作者*/
MODULE_DESCRIPTION("HELLO");
MODULE_VERSION("1.0"); //版本号
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 );
printk(KERN_ALERT"module version:%s\n",THIS_MODULE->version);
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 );
printk("find_module bye...\n");
}
module_init(hello_init);
module_exit(hello_exit);
insmod
Aug 26 23:34:02 ubuntu kernel: [24132.078806] this module: ffffffffa0354000==ffffffffa0354000
Aug 26 23:34:02 ubuntu kernel: [24132.078939] module state: 1
Aug 26 23:34:02 ubuntu kernel: [24132.079010] module name: kmodule
Aug 26 23:34:02 ubuntu kernel: [24132.079086] module version:1.0
Aug 26 23:34:02 ubuntu kernel: [24132.079159] module name: kmodule
Aug 26 23:34:02 ubuntu kernel: [24132.079235] module name: snd_ens1371
Aug 26 23:34:02 ubuntu kernel: [24132.079316] module name: gameport
Aug 26 23:34:02 ubuntu kernel: [24132.079394] module name: snd_rawmidi
Aug 26 23:34:02 ubuntu kernel: [24132.079475] module name: snd_seq_device
Aug 26 23:34:02 ubuntu kernel: [24132.079638] module name: snd_ac97_codec
Aug 26 23:34:02 ubuntu kernel: [24132.079727] module name: joydev
Aug 26 23:34:02 ubuntu kernel: [24132.079803] module name: ac97_bus
Aug 26 23:34:02 ubuntu kernel: [24132.079881] module name: ppdev
Aug 26 23:34:02 ubuntu kernel: [24132.080008] module name: snd_pcm
Aug 26 23:34:02 ubuntu kernel: [24132.080090] module name: irda
Aug 26 23:34:02 ubuntu kernel: [24132.080162] module name: psmouse
Aug 26 23:34:02 ubuntu kernel: [24132.080885] module name: snd_timer
Aug 26 23:34:02 ubuntu kernel: [24132.080970] module name: snd
Aug 26 23:34:02 ubuntu kernel: [24132.081041] module name: serio_raw
Aug 26 23:34:02 ubuntu kernel: [24132.081122] module name: hid_generic
Aug 26 23:34:02 ubuntu kernel: [24132.081204] module name: soundcore
Aug 26 23:34:02 ubuntu kernel: [24132.081284] module name: crc_ccitt
Aug 26 23:34:02 ubuntu kernel: [24132.081363] module name: vmwgfx
Aug 26 23:34:02 ubuntu kernel: [24132.081439] module name: ttm
Aug 26 23:34:02 ubuntu kernel: [24132.081529] module name: drm
Aug 26 23:34:02 ubuntu kernel: [24132.081600] module name: parport_pc
Aug 26 23:34:02 ubuntu kernel: [24132.081681] module name: nfsd
Aug 26 23:34:02 ubuntu kernel: [24132.081753] module name: nfs_acl
Aug 26 23:34:02 ubuntu kernel: [24132.081830] module name: auth_rpcgss
Aug 26 23:34:02 ubuntu kernel: [24132.081912] module name: oid_registry
Aug 26 23:34:02 ubuntu kernel: [24132.081996] module name: nfs
Aug 26 23:34:02 ubuntu kernel: [24132.082067] module name: fscache
Aug 26 23:34:02 ubuntu kernel: [24132.082144] module name: lockd
Aug 26 23:34:02 ubuntu kernel: [24132.082218] module name: sunrpc
Aug 26 23:34:02 ubuntu kernel: [24132.082293] module name: i2c_piix4
Aug 26 23:34:02 ubuntu kernel: [24132.082373] module name: shpchp
Aug 26 23:34:02 ubuntu kernel: [24132.082449] module name: mac_hid
Aug 26 23:34:02 ubuntu kernel: [24132.082543] module name: lp
Aug 26 23:34:02 ubuntu kernel: [24132.082614] module name: parport
Aug 26 23:34:02 ubuntu kernel: [24132.082690] module name: usbhid
Aug 26 23:34:02 ubuntu kernel: [24132.082766] module name: hid
Aug 26 23:34:02 ubuntu kernel: [24132.082837] module name: e1000
Aug 26 23:34:02 ubuntu kernel: [24132.082911] module name: mptspi
Aug 26 23:34:02 ubuntu kernel: [24132.082988] module name: mptscsih
Aug 26 23:34:02 ubuntu kernel: [24132.083067] module name: mptbase
Aug 26 23:34:02 ubuntu kernel: [24132.083145] module name: floppy
Aug 26 23:34:02 ubuntu kernel: [24132.083221] module name: vmw_pvscsi
Aug 26 23:34:02 ubuntu kernel: [24132.083302] module name: vmxnet3
Aug 26 23:34:07 ubuntu kernel: [24137.128046] module state: 2
Aug 26 23:34:07 ubuntu kernel: [24137.128135] find_module bye...
85 #define THIS_MODULE (&__this_module)
是一个struct module变量,代表当前模块,与那个著名的current有几分相似,可以通过THIS_MODULE宏来引用模块的struct module结构,比如使用THIS_MODULE->state可以获得当前模块的状态。现在你应该明白为啥在那个岁月里,你需要毫不犹豫毫不迟疑的将struct usb_driver结构里的owner设置为THIS_MODULE了吧,这个owner指针指向的就是你的模块自己。那现在owner咋就说没就没了那?这个说来可就话长了,咱就长话短说吧。不知道那个时候你有没有忘记过初始化owner,反正是很多人都会忘记,大家都把注意力集中到probe、 disconnect等等需要动脑子的角色上面了,这个不需要动脑子,只需要花个几秒钟指定一下的owner反倒常常被忽视,这个就是容易得到的往往不去珍惜,不容易得到的往往日日思量着去争取。于是在2006年的春节前夕,在咱们都无心工作无心学习等着过春节的时候,Greg坚守一线,去掉了 owner,于是千千万万个写usb驱动的人再也不用去时刻谨记初始化owner了。咱们是不用设置owner了,可core里不能不设置,struct usb_driver结构里不是没有owner了么,可它里面嵌的那个struct device_driver结构里还有啊,设置了它就可以了。于是Greg同时又增加了usb_register_driver()这么一层,usb_register()可以通过将参数指定为THIS_MODULE去调用它,所有的事情都挪到它里面去做。反正usb_register() 也是内联的,并不会增加调用的开销。
http://blog.csdn.net/jk110333/article/details/8563647