Total Pageviews

Tuesday 15 March 2016

Linux系统如何正确使用和安装内核模块

模块是Linux内核支持的一种动态加载的组件,大多数的模块是驱动程序。而且Linux的模块设计成可以堆叠式的----就是一个模块运行在另一 个模块之上,这个模块也可能再为它上面的模块提供支持,当然所有的模块又都运行在内核之上。这样一来一个模块就可能依赖于另一个模块提供的服务,或者内核 提供的服务。在安装这个模块时,安装程序就需要知道这些依赖关系并先于模块本身,安装其他依赖的模块。下面的程序和文件完成整个模块安装和维护过程
modules.dep          模块依赖信息,位于/lib/modules/<kernel version>/
modprobe               安装模块程序,他自动读取当前版本内核的内核模块modules.dep并,安装模块和依赖的模块。
insmod                   极简单的安装模块程序,他只是安装模块并不做任何依赖性处理,实用性不大,modprobe更聪明一些
depmod                   模块依赖信息维护程序 ,他根据当前/lib/modules/<kernel version>/ 的模块信息生成或更新modules.dep,正常情况下,当编译完内核时,make modules_install的结尾部份将执行depmod.
System.map           内核导出符号表,详细内容下面介绍。
如果想要安装一个已编译好的内核模块,典型过程如下:
将这个编译好的模块cp到/lib/modules/`uname -r`/kernel/driver/mymod/ 目录中,然后
运行depmod生成模块依赖,最后运行 modprobe
可以执行如下命令实现:
root# mkdir -p /lib/modules/`uname -r`/kernel/driver/mymod  #注意不是单引号,是反引号。
root# cp <my_module.ko> /lib/modules/`uname -r`/kernel/driver/mymod/
root# depmod -eF /boot/System.map-`uname -r` -A   #注意是否存在/boot/System.map-<verion number>,没有的话需要从内核编译后的映像所在目录copy过来。实在没有的话用depmod -A代替。但结果可能不准确。
root# modprobe -v my_module       #注意观察输出的信息,看加载模块是否成功,另外modprobe比insmod更聪明,insmod太简单没有什么实用价值
如果仍然出现段错误,基本上可以证明该模块不能工作于目前的内核。
为了避免出现段错误,最安全的做法,重新编译内核并打开下面两个选项
[*]   Module versioning support                                     
[*]   Source checksum for all modules
确保内核拒绝不兼容的模块
然后重复前面的步骤,这时modprobe将拒绝安装不兼容的模块,也就是说,这时如果成功安装,那么就决不会出现段错误。否则,modprobe或insmod会失败。
System.map是在编译内核时产生的,记录内核的导出符号.
depmod -A可以以追加方式生成模块依赖modules.dep.但是它只能生成模块之间的依赖,对于模块中出现的其他模块也没有提供的未解决符号,depmod 不再进行解析,认为这个符号由内核提供,事实上,这个未解决符号内核可能也没有提供,这时运行时就可能出现段错误。
如果用-eF System.map选项后,depmod除了会在模块间解析符号外,还会对照内核导出符号表System.map来更精确的确定哪些符号是真正无法解决的符号。并在标准输出上给出这些未解决符号的信息。