内核模块的初始化函数,撤消函数通常是这样的形式:
static int __init xxx-init(.....); //函数没有参数就写void,init前是两个_
static void __exit xxx-exit(....);
其中__init属性标志, 表明该段代码位于代码段的子段初始化段,初始化段的程序只执行一次,执行完后它所占用的内存空间将被回收。当模块加载时, __init属性的函数就被执行;
__exit修饰词标记函数只在模块卸载时使用,如果模块被直接编进内核则该函数就不会被调用。如果内核编译时没有包含该模块,则此标记的函数将被简单地丢弃。
了解:
内核中多个struct module结构体模块的集合会形成一个链表,通过insmod(实际执行module_init系统调用)把本模块插入集合,相当于插入链表当中。
struct module
{
enum module_state state;
struct list_head list;
char name[MODULE_NAME_LEN];
{
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;
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;
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_gpl_syms;
const unsigned long *gpl_crcs;
unsigned int num_exentries;
const struct exception_table_entry *extable;
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;
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
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;
};
Elf_Sym *symtab;
unsigned long num_symtab;
char *strtab;
struct module_sect_attrs *sect_attrs;
#endif
void *percpu;
char *args;
};