2.6内核中网络模块调用入口

[原文:http://blog.csdn.net/ZHENG017/archive/2006/04/26/678484.aspx]

刚下了一份2.6.16的kernel,比情景分析中的讲解变得太多了,在/init/main.c中,start_kernel创建了init核 心进程后,没找到网络模块的调用入口.???那就反向来吧,找af_inet.c中输出了什么东西让kernel可以调用.呵呵,inet_init,这 个是不用怀疑吧,可是用source in sight搜索了整个工程,都没看到调用了inet_init.???

在inet_init后紧接着是:module_init(inet_init);声明成模块了,可以静态连入kernel也可做为module动态insmod.

而在include\linux\init.h中将module_init 声明为:#define module_init(x) __initcall(x);而__initcall又声明为#define __initcall(fn) device_initcall(fn);而device_initcall为#define device_initcall(fn)  __define_initcall("6",fn);__define_initcall为#define __define_initcall(level,fn) \
 static initcall_t __initcall_##fn __attribute_used__ \
 __attribute__((__section__(".initcall" level ".init"))) = fn

在arch\i386\kernel\vmlinux.lds.s中定义了initcall.init这样一个section:如下:

  __initcall_start = .;
  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 *(.initcall1.init)
 *(.initcall2.init)
 *(.initcall3.init)
 *(.initcall4.init)
 *(.initcall5.init)
 *(.initcall6.init)
 *(.initcall7.init)
  }
  __initcall_end = .;

也就是说当将一个原本由init()显示调用的function声明为module后,其module_init函数会ld在链接时,会根据其优先 级??(1为core_initcall,2为postcore_initcall,在init.h中有相应定义)链接到initcall.init 这个section中相应位置,越靠前就越先执行.(还是对ld不熟).  :(

这样具体再来看:start_kernel() --->init() ---->do_basic_setup() --->do_initcalls();

这个就是一部分do_initcalls的代码了,

static void __init do_initcalls(void)

{

initcall_t *call;

for (call = __initcall_start; call < __initcall_end; call++) {

....

(*call)();

}

在这段代码中,从initcall.init 节中取出所有的initcall,其实就是4个byte的function pointer,再执行.很容易看出来,core_initcall比device_initcall要优先级高些.
posted @ 2009-09-17 20:48  YY哥  阅读(480)  评论(0编辑  收藏  举报