之前写的好像不太对,我的理解:
输入insmod xxx.ko之后(基于linux3.5版本)
- linux 系统会调用linux/kernel/module.c里面的sys_init_modul函数
- sys_init_modul函数先做一些校验,之后进行关键的两步
mod = load_module(umod, len, uargs);//模块加载
ret = do_one_initcall(mod->init);//模块init函数调用 - load_module模块加载分四步
copy_and_check将模块从用户空间拷贝到内核空间,
layout_and_allocate为模块进行地址空间分配,
simplify_symbols为模块进行符号解析,
apply_relocations为模块进行重定位。 - do_one_initcall就是我们自己写的module_init()驱动函数。
在此需要另外说几点:
xxx.ko是目标文件,无法直接运行,需要链接后才可以运行,因此就就需要进行3的load_module模块加载的那几步。有关重定位的知识见此博客:https://blog.csdn.net/gyyu32g/article/details/78508406
链接(Link)
目标文件经过链接(Link)以后才能变成可执行文件。既然目标文件和可执行文件的格式是一样的,为什么还要再链接一次呢,直接作为可执行文件不行吗?
不行的!因为编译只是将我们自己写的代码变成了二进制形式,它还需要和系统组件(比如标准库、动态链接库等)结合起来,这些组件都是程序运行所必须的。
链接(Link)其实就是一个“打包”的过程,它将所有二进制形式的目标文件和系统组件组合成一个可执行文件。完成链接的过程也需要一个特殊的软件,叫做链接器(Linker)。
随着我们学习的深入,我们编写的代码越来越多,最终需要将它们分散到多个源文件中,编译器每次只能编译一个源文件,生成一个目标文件,这个时候,链接器除了将目标文件和系统组件组合起来,还需要将编译器生成的多个目标文件组合起来。