三,Makefile.modpost文件
在script目录下有许多Makefile文件,由于各种情况;其中,Makefile.modpost由于module的生成。
第一步:
a) 编译驱动的每个.o文件。
b)将每个.o文件链接到.o。
c)在$(MODVERDIR)/生成一个.mod文件,列出.ko及每个.o文件。
第二步:
1)找出所有在$(MODVERDIR)/的modules。
2)接着使用modpost
3)为每个module创建.mod.c
4)创建一个Module.symvers文件,保存了所有引出符号及其CRC校验。
5)编译全部 .mod.c文件。
6)链接所有的module成为一个文件。
第三步:替换module里一些ELF段,包括:
Version magic (see include/vermagic.h for full details)
Kernel release
SMP is CONFIG_SMP
PREEMPT is CONFIG_PREEMPT
GCC Version
Module info
Module version (MODULE_VERSION)
Module alias'es (MODULE_ALIAS)
Module license (MODULE_LICENSE)
See include/linux/module.h for more details
第四步:
Step 4 is solely used to allow module versioning in external modules,
where the CRC of each module is retrieved from the Module.symers file.
KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
symbols in the final module linking stage
KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
This is solely usefull to speed up test compiles
具体清参考Makefile.modpost文件。
四,驱动模块的本质
编译完驱动后,会在驱动源码目录下生成一个<驱动>.mod.c文件
其内容如下:
#include
#include
#include
MODULE_INFO(vermagic, VERMAGIC_STRING);
struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const char __module_depends[]
__attribute_used__
__attribute__((section(".modinfo"))) =
"depends=xxxx,yyyy";
MODULE_ALIAS("pci:v0000104Cd0000A106sv*sd*bc*sc*i*");
其实就是在生成的文件里加入".gnu.linkonce.this_module"这样一个段,驱动加裁时会找到这个段并调用.init函数。
阅读(5204) | 评论(0) | 转发(0) |