Linux Module浅析

本文解析了Linux内核中模块加载的流程,详细介绍了module_init()和module_exit()宏的作用及其实现方式,同时阐述了insmod命令的工作原理。

1. module_init() / module_exit()

include/linux/init.h

module_init()函数修饰模块的入口函数。根据是否定义MODULE,module_init()这个宏有不同的展开。

没有定义MODULE时,模块与内核链接成一个文件,module_init()修饰的函数被内核
177 #define __define_initcall(level,fn,id) \
178         static initcall_t __initcall_##fn##id __used \
179         __attribute__((__section__(".initcall" level ".init"))) = fn
207 #define device_initcall(fn)             __define_initcall("6",fn,6)
212 #define __initcall(fn) device_initcall(fn)
258 /**
259  * module_init() - driver initialization entry point
260  * @x: function to be run at kernel boot time or module insertion
261  *
262  * module_init() will either be called during do_initcalls() (if
263  * builtin) or at module insertion time (if a module).  There can only
264  * be one per module.
265  */
266 #define module_init(x)  __initcall(x);

arch/arm/kernel/vmlinux.lds文件确定了内核链接之后的代码布局。其中__initcall_start到__initcall_end之间就是由__define_initcall()宏定义的一些变量(实际上是函数指针),这些变量的值就是各module_init()修饰的函数的地址。
start_kernel()
  -> rest_init()
     -> 创建kernel_init线程,执行kernel_init函数
kernel_init()
  -> do_pre_smp_initcalls()
do_pre_smp_initcalls()函数中依次调用__initcall_start到__initcall_end之间的函数指针。

定义了MODULE宏,则module_init()宏定义如下。
295 #define module_init(initfn)                                     \
296         static inline initcall_t __inittest(void)               \
297         { return initfn; }                                      \
298         int init_module(void) __attribute__((alias(#initfn)));

即模块入口函数统一都有一个别为init_module的别名。

2. insmod

insmod先检查ko文件的ELF标志,然后直接调用系统调用init_module()来做所有的工作。
kernel/module.c中有init_module系统调用。

转载于:https://www.cnblogs.com/sammei/archive/2013/03/04/3295600.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值