加载内核模块-Unknown symbol错误分析
Unknown symbol 说明 有些函数不知道(未定义)。
在调试过程中,发现一个问题,编译生成一个KO文件,insmod加载后报错:
Unknown symbol var_set_integer (err 0)
Unknown symbol parse_arg_eq (err 0)
问题分析思路:
一、用命令查看内核中是否已有这个内核符号,
例如要查看是否有var_set_integer这个内核符号,输入命令:
#cat /proc/kallsyms | grep "var_set_integer"
没有相关打印,而输入其它的函数名则会有打印信息。
如果内核中已经包含了这个符号,那么就会有相关的打印信息,否则不打印。
注:
/proc/kallsyms会显示内核中所有的符号,但是这些符号不是都能被其他模块引用的(绝大多数都不能),能被导出的是符号的类型是大写的那些(例如T,U)。
二、使用modinfo查看内核相关信息,确定模块依赖关系,再进一步确认符号调用。
例如:
[root@localhost sw_64-3_8]# modinfo linux-bcm-core.ko
filename: linux-bcm-core.ko
license: GPL //权限
description: BCM Core Device Driver
depends: linux-kernel-bde // 由此可看出linux-bcm-core.ko 依赖于linux-kernel-bde.ko
vermagic: 3.8.0-sw2f SMP mod_unload modversions //内核版本
三、在源码中搜索这几个函数定义的地方,看是否有使用EXPORT_SYMBOL,是否有extern声明;
并且查看是否要做GPL声明:修改为 MODULE_LICENSE("GPL");
(1)如果你的模块需要输出符号给其他模块使用, 应当使用下面的宏定义:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);//只用于包含 GPL 许可权的模块。
符号必须在模块文件的全局部分输出, 在任何函数之外, 因为宏定义扩展成一个特殊用途的并被期望是全局存取的变量的声明. 这个变量存储于模块的一个特殊的可执行部分( 一个 "ELF 段" ), 内核用这个部分在加载时找到模块输出的变量.
(2)EXPORT_SYMBOL使用方法:
1)在模块函数定义之后使用EXPORT_SYMBOL(函数名);
2)在调用该函数的模块中使用extern对之声明;
3)首先加载定义该函数的模块,再加载调用该函数的模块。【模块加载顺序的前后要求,一般就是依赖于符号调用】
编译生成ko模块之后,用insmod命令加载此模块到内核。这个程序加载模块的代码段和数据段到内核。
接着, 连接模块中任何未解决的符号到内核的符号表上.
也就是说:
【insmod使用公共内核符号表来解析模块中未定义的符号】,公共内核符号表中包含了所有的全局内核项(即函数和变量)的地址,这是实现模块化驱动程序所必需的。
同时也可以【导出自身模块中的任何内核符号到公共内核符号表】,如图:
在通常情况下,模块只需实现自己的功能,而无需导出任何符号。但是,如果其他模块需要从某个模块中获得好处时,我们也可以导出符号。
四、在模块目录下查看Module.symvers,看是否存在要找的符号。
Module.symvers contains a list of all exported symbols from a kernel build.
Module.symvers包含所有要导出的列表符号。
Module.symvers file 的语法格式:
<CRC> <Symbol> <module>
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
当内核编译选项CONFIG_MODVERSIONS关闭时,所有的CRC值都为0x00000000。
补充:
1,
【 Linux模块间通讯方法非常的多,最便捷的方法莫过于函数符号导出,然后直接调用。】
2,
驱动也是存在于内核空间的,它的每一个函数每一个变量都会有对应的符号,这部分符号也可以称作内核符号,
它们不导出(EXPORT_SYMBOL)就只能为自身所用,导出后就可以成为公用,对于导出的那部分内核符号就是我们常说的内核符号表。
insmod的时候并不是所有的函数都得到内核符号表去寻找对应的符号,
每一个驱动在自已的分配的空间里也会存在一份符号表,里面有关于这个驱动里使用到的变量以及函数的一些符号,首先驱动会在这里面找,如果发现找不到就会去公共内核符号表中搜索,搜索到了则该模块加载成功,搜索不到则该模块加载失败。
2.6内核默认情况下,是不会在模块加载后把模块中的非静态全局变量以及非静态函数自动导出到内核符号表中的,需要显式调用宏EXPORT_SYMBOL才能导出。
对于一个模块来讲,如果仅依靠自身就可以实现自已的功能,那么可以不需要要导出任何符号,只有其他模块中需要使用到该模块提供的函数时,就必须要进行导出操作。
由此启发,因为LKM中所存取的每一个符号(像函数名)也会被列在内核符号表中,有时候我们可以看内核符表就可以看到LKM调用的那些函数,如果这个LKM为非法目的,那么我们可以杀掉这个LKM.
名词解释:【LKM:可装载模块(Loadable Kernel Module )】
参考:
http://lxr.free-electrons.com/source/Documentation/kbuild/modules.txt
http://blog.csdn.net/macrossdzh/article/details/4601648
http://secisland.blog.51cto.com/787880/319760
转自:http://blog.csdn.net/wuyongpeng0912/article/details/46739233
加载内核模块-Unknown symbol错误分析的更多相关文章
- Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块
Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块 http://baike.baidu.com/link?url=lxiKxFvYm-UfJIxMjz ...
- CentOS启动时自动加载内核模块
要想在CentOS中自动加载内核模块,需要在/etc/sysconfig/modules/目录中增加一个脚本,在此脚本中加载所需的模块. 下面是我所用的一个名为8021q.modules的脚本,用来在 ...
- 爱之初体验---编译加载内核模块hello
1. hello.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h ...
- 内核加载模块时出现Unknown symbol等提示
一.背景 1.更改了内核的配置,重新编译了内核 2.未重新编译内核模块 3.板子上只更新了内核,并未更新文件系统 二.分析 发现是在加载内核模块时出现Unknown symbol等信息,恰逢当时只更新 ...
- insmod: can't insert 'xxx.ko': unknown symbol in module, or unknown parameter
手动加载内核模块时候,报如下错误信息 insmod: can't insert 'xxx.ko': unknown symbol in module, or unknown parameter 问题原 ...
- insmod 时报错“Unknown symbol”问题的解决
在加载驱动模块时报错: “ Unknown symbol CFG80211_SupBandReInit (err 0)” 查看了内核代码以及加载上的symbol(命令为 cat /proc/kalls ...
- linux内核裁剪及编译可加载模块
一:linux内核裁剪: 1:编译内核源码: 今天的重点内容是内核驱动的编写,在编写驱动之前首先的了解linux内核源码,linux主要是由五个子系统组成:进程调度,内存管理,文件系统,网络接口以及进 ...
- CentOS中自动加载802.1q模块
要想在CentOS中自动加载内核模块,需要在/etc/sysconfig/modules/目录中增加一个脚本,在此脚本中加载所需的模块. 下面是我所用的一个名为8021q.modules的脚本,用来在 ...
- linux内核及其模块的查询,加载,卸载 lsusb等
http://blog.sina.com.cn/s/blog_53e81e2a0100zkxi.html 1,/sbin/update-modules文件,他是一个linux通用的模块管理脚本程序. ...
随机推荐
- linux 下 iscsi的简单使用
一.准备工作 1.1.(服务端和客户端都需要设置) 系统使用的是CentOS6.8 禁用防火墙: 查看状态:# service iptables status 停止:# systemctl sto ...
- [置顶]
flume高并发优化——(15)中间件版本升级
在系统平稳运行一年的基础上,为提供更好的服务,现针对java,kafka,flume,zk,统一进行版本升级,请各位小伙伴跟着走起来,不要掉队啊! 名称 老版本号 新版本号 jdk 1.7.0_25 ...
- 神奇的 ViewDragHelper,让你轻松定制拥有拖拽能力的 ViewGroup
为了吸引大家的注意力,先给大家看一张动图: 相信这种效果大家都见过吧?我第一次见到这样的效果时,心里也痒痒的,急于想实现这种功能,后来因为拖延症的问题,就一直没有去弄这件事.现在这段时间,工作比较轻闲 ...
- android代码常识
查看当前android代码版本号:build/core/version_defaults.mk---->查找platform_version android源码在线阅读网址 http://and ...
- arduino 编程基础
0. setup() 与 loop() 函数 void setup(): // put your setup code here, to run once: 仅执行一次: void loop(): / ...
- vue轮播图
vue开发中遇到这样一个需求实现导航栏和中间内容相结合实现页面滑动导航跟随改变的效果.看效果: 这里我用的是vue所带的插件:vue-awesome-swiper,传送门:https://www.np ...
- 再也不用克隆多个仓库啦!git worktree 一个 git 仓库可以连接多个工作目录
我在 feature 分支开发得多些,但总时不时被高优先级的 BUG 打断需要临时去 develop 分一个分支出来解 BUG.git 2.6 以上开始提供了 worktree 功能,可以解决这样的问 ...
- Java linux lame .wav音频转mp3 并且压缩
public class Test{ public static void main(String[] args) {try{ String shellString = "lame -b 1 ...
- vs2013 boost signals
#include "stdafx.h" #include <boost/signals2/signal.hpp> #include <iostream> u ...
- YARN的Fair Scheduler和Capacity Scheduler
关于Scheduler YARN有四种调度机制:Fair Schedule,Capacity Schedule,FIFO以及Priority: 其中Fair Scheduler是资源池机制,进入到里面 ...