栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

模块生成过程

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模块生成过程

模块生成过程

文章目录
  • 模块生成过程
    • 模块编译过程
    • modpost
      • `read_dump()/write_dump()`导入/导出符号信息
      • `read_symbols()`从ELF文件中读取符号并记录
      • `check_exports()`检查符号与GPL协议匹配情况
      • 生成.mod.c文件
      • module-common.lds

先看图:

模块编译过程

首先看一下普通外部模块编译的过程,这里用ldd3的某些驱动来演示,执行下面命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- M=/home/mj/work/ldd3-master/misc-modules modules O=./out V=1

过程显示如下:

make -C /home/mj/work/linux-4.0/out KBUILD_SRC=/home/mj/work/linux-4.0 
-f /home/mj/work/linux-4.0/Makefile modules
make[1]: Entering directory '/home/mj/work/linux-4.0/out'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || (	
echo >&2;							
echo >&2 "  ERROR: Kernel configuration is invalid.";		
echo >&2 "         include/generated/autoconf.h or include/config/auto.conf are missing.";
echo >&2 "         Run 'make oldconfig && make prepare' on kernel src to fix it.";	
echo >&2 ;							
/bin/false)
mkdir -p /home/mj/work/ldd3-master/misc-modules/.tmp_versions ; rm -f /home/mj/work/ldd3-master/misc-modules/.tmp_versions
0x00000000	fsg_fs_function	drivers/usb/gadget/function/usb_f_mass_storage	EXPORT_SYMBOL_GPL
...
0x00000000	class_interface_unregister	vmlinux	EXPORT_SYMBOL_GPL
...
0x00000000	memmove	vmlinux	EXPORT_SYMBOL
..

读出符号和所在的模块信息后,对信息进行一个记录,模块就放到模块的记录链表中,符号放到记录符号的链表中。


模块的查找和申请也很简单,就是链表的操作:

导出模块符号时,需要注意到不能出现相同的符号,否则这里会给出警告:

在符号的记录与查找时,利用了hash数组去加快查找速度:

至于导出符号的类型,可以看export_list:

至于write_dump(),遍历hash数组判断是否需要导出相关符号即可。

对于正常构建,始终转储所有符号。
对于外部模块,仅转储未从内核模块中读取的符号。

read_symbols()从ELF文件中读取符号并记录

read_symbols_from_files()从-T选项输入的.o文件中读取相关的符号信息,而主要是这个 read_symbols() 函数。

read_symbols()就是对ELF文件校验后,读出里面的符号表信息,并记录在当前运行的环境中。

parse_elf()解析elf文件,主要是校验ELF头,读取各个section的位置后,找到与模块信息相关的sectnon,比如.modinfo模块信息,__ksymtab导出符号等,最主要的其实是符号表SHT_SYMTAB,这里面记录的就是函数名、变量名等字符串信息。将符号表的起始地址和结束地址记录,方便后续使用。





get_modinfo()是从前面parse_elf()记录的.modinfo里面获取相关的信息,比如里面的license,version。

比如这样:license=GPL。

handle_modversions()主要就是把未定义的符号和要导出的符号先记录下来。


check_exports()检查符号与GPL协议匹配情况

check_exports()检查模块所用到的符号是否与GPL协议相悖。

检查协议的如下:

导出的符号的过程在上面的export_from_secname()或export_from_sec(),在handle_modversions()时:

生成.mod.c文件

输出头文件信息、.gnu.linkonce.this_module节,以及init,exit等相关信息。

add_versions()增加modversion_info,警告为定义符号等。

其实到.mod.c生成了,整个模块到生成模块基本就完成了。剩下的就是把.mod.c生成的.mod.o和原来的.o文件进行一个链接。

module-common.lds

这个直接看就好了,对各种___ksymtab,___ksymtab_gpl等符号进行排序,init_array进行ALIGN(8)对齐。

好了,模块生成就暂时这样把。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/335514.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号