kbuild系统-编译到内核和编译成模块的区别

36 篇文章 0 订阅
 代码编译到内核和编译成模块在代码中有什么区别呢?

  从模块的代码中看是一样的。入口函数都是MODULE_init(fun),但是代码中的条件编译会使宏module_init()在编译到内核和编译成模块的情况下替换成不同的代码。

  include/linux/init.h中可知

  #ifndef MODULE

  ...

  #define module_init(x) __initcall(x);

  ...

  #else /* MODULE */

  ...

  /* Each module must use one module_init(), or one no_module_init */

  #define module_init(initfn) \

  static inline initcall_t __inittest(void) \

  { return initfn; } \

  int init_module(void) __attribute__((alias(#initfn)));

  ...

  #endif

  当代码编译成模块时,会定义MODULE宏,否则不会。因为在/usr/src/linux/Makefile中可以看到

  336 MODFLAGS = -DMODULE

  337 CFLAGS_MODULE = $(MODFLAGS)

  338 AFLAGS_MODULE = $(MODFLAGS)

  这两个变量又被export成为全局变量。所以可以知道,在编译成模块时,会有MODULE这个宏。

  由以下代码可以知道

  #define __initcall(fn) device_initcall(fn)

  #define device_initcall(fn) __define_initcall("6",fn)

  085 #define __define_initcall(level,fn) \

  086 static initcall_t __initcall_##fn __attribute_used__ \

  087 __attribute__((__section__(".initcall" level ".init"))) = fn

  前者实际上是编译入内核中的.initcall6.init 这个section

  而在

  arch/i386/kernel/vmlinux.lds.S中可以知道:

  083 __initcall_start = .;

  084 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {

  085 *(.initcall1.init)

  086 *(.initcall2.init)

  087 *(.initcall3.init)

  088 *(.initcall4.init)

  089 *(.initcall5.init)

  090 *(.initcall6.init)

  091 *(.initcall7.init)

  092 }

  093 __initcall_end = .;

  arch/i386/kernel/vmlinux.lds.S

  .initcall6.init是.initcall.init的一部分

  执行顺序:

  start_kernel->rest_init

  系统启动后在rest_init中会创建init内核线程

  init->do_basic_setup->do_initcalls

  do_initcalls中会把.initcall.init中的函数依次执行一遍

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

  ...

  (*call)();

  ...

  }

  于是执行了module_init(fn)函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值