struct module
{
unsigned long size_of_struct;
struct module *next;
const char *name;
unsigned long size;
union
{
atomic_t usecount;
long pad;
}uc;
unsigned long flags;
unsigned nsyms;
unsigned ndeps;
struct module_symbol *syms;
struct module_ref *deps;
struct module_ref *refs;
int (*init)(void);
void (*cleanup)(void);
const struct exception_table_entry *ex_table_start;
const struct exception_table_entry *ex_table_end;
#ifdef __alpha__
unsigned long gp;
#endif
const struct module_persist *persist_start;
const struct module-persist *persist_end;
int (*can_unload)(void);
int runsize;
const char *kallsyms_start;
const char *kallsyms_end;
const char *archdata_start;
const char *archdata_end;
const char *kernel_data;
};
struct module_symbol
{
unsigned long value;
const char *name;
}
struct module_ref
{
struct module *dep; /*"parent"pointer*/
struct module *ref; /*"child"pointer*/
struct module_ref *next_ref;
}
struct kernel_sym
{
unsigned long value;
char name[60];
};
//启动内核模块的初始化
void __init int_modules(void)
{
kernel_module.nsyms=__stop___ksymtab-__start___ksymtab;
arch_init_modules(&kernel_module);
}
//创建一个新模块
asmlinkage unsigned long sys_create_modules(const char *name_user,size_t size)
{
char *name;
long namelen,error;
struct module *mod;
unsigned long flags;
if(!capable(CAP_SYS_MODULE)) //验证是否由权限执行
{
return -EPERM;
}
lock_kernel();
if((namelen=get_mod_name(name_user,&name))<0) //从内核空间中申请一个页面,将用户空间的名称拷贝到内核空间
{
error=namelen;
goto err0;
}
if(size<sizeof(struct module)+namelen) //检查入口参数size的长度,这个长度不能小于module{}结构的长度和模块的名称字符串的长度的和
{
error=-EINVAL;
goto err1;
}
if(find_module(name)!=NULL) //在模块联表中查找是否已经有名为name的模块
{
error=-EEXIST;
goto err1;
}
if((mod=(struct module*)module_map(size))==NULL) //module_map()宏取得内核空间用来存放模块数据的内存
{
error=-ENOMEM;
goto err1;
}
memset(mod,0,sizeof(*mod));
mod->size_of_struct=sizeof(*mod);
mod->name=(char*)(mod+1);
mod->size=size;
memcpy((char*)(mod+1),name,namelen+1);
put_mod_name(name); //释放name所占用的空间
spin_lock_irqsave(&modlist_lock,flags); //把该module结构加到原来模块联表的头上
mod->next=module_list;
module_list=mod;
spin_unlock_irqrestore(&modlist_lock,flags);
error=(long)mod; //获得创建模块的地址
goto err0;
err1:
put_mod_name(name);
err0:
unlock_kernel();
return error; //返回模块的地址
}