Linux Module浅析

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/p/3295600.html