Chinaunix首页 | 论坛 | 博客
  • 博客访问: 617510
  • 博文数量: 178
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 2162
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 20:06
文章分类

全部博文(178)

文章存档

2011年(1)

2010年(94)

2009年(86)

我的朋友

分类:

2009-12-02 08:30:20

From: http://blog.chinaunix.net/u/7547/showart_250497.html

在Linux中有大量的module存在,因为module能减少内核大小,能达到相同的效果。看了下内核中对module的 处理,主要是模块的创建和对module结构的初始化。
主要涉及到module_symbol,module_ref,module这三个数据结构,都在include/linux/module.h中定义。
struct module_symbol
{
     unsigned long value;
     const char *name;
};
这个结构用来描述符号的名字和值
struct module_ref
{
     struct module *dep;
     struct module *ref;
     struct module_ref *next;
};
这个结构用来描述模块之间的依赖关系,dep表示本模块所依赖的模块,可能是其他模块也可能是内核,内核也是个模块,将内核也定义一个module,
static struct module kernel_module = {
     size_of_struct: sizeof(struct module),
     name: "",
     uc:   {ATOMIC_INIT(1)},
     flags:MOD_RUNNING,
     syms: __start__ksymtab,
     ex_table_start: __start__ex_table,
     ex_table_end:   __end__ex_table,
     kallsyms_start: __start_kallsyms,
     kallsyms_end:   __stop__kallsyms,
};
ref表示其他模块对本模块的引用,然后通过next来构成一个链表。
struct module_persisit;//empty
struct module
{     
     unsigned long size_of_struct; /* sizeof(module) */
     struct module *next;//用来构成链
     const char *name;//模块名称
     unsigned long size;//模块大小
     union {
          atomic_t usecount;
          long pad;
     } uc;//使用次数
     unsigned long flags; /* AUTOCLEAN et al */
     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;
/* Members past this point are extensions to the basic
module support and are optional. Use mod_opt_member()
to examine them. */
     const struct module_persisit *persist_start;//扩展
     const struct module_persisit *persist_end;
     int (*can_unload)(void);
};
每个已安装模块在内核中都有一个module数据结构(通过create_module()创建)
创建module的流程为调用sys_create_module()来创建一个struct module,然后就是用sys_init_module()来对module结构进行初始化,从用户空间复制相关成分来填充module结构。
module这个结构大小是一定的,但是其映象空间大小就因模块的不同而不同了。persist_start,persist_end是为了处理用户空间模块大小和内核模块大小不符造成的麻烦,所以在检查时第一要不小于persist_start前面的部分
mod_usr_size>(unsigned long)&((struct module *)0L)->persist_start
第二要小于persist_end+64bytes,mod_usr_size
对于扩展部分的检验用mod_member_present宏来处理,原型为
#define mod_member_present(mod,member) \
((unsigned long)&((struct module *)0L)->member+1) <= (mod)->size_of_struct,
进行完权限以及以上的校验后就可以从用户空间将module结构的相关成分复制过来了,然后就是将module_ref链到相应的模块,最后还要启动执行模块的init_module()函数。
而对模块的卸载则是通过sys_delete_module()来实现的,在该函数中只要将module_ref从相应的链中删除,并且将module结构所占用的空间释放即可。
阅读(953) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~