【4】模块扩展部分—模块依赖-导出符号表
当模块之间存在依赖关系需注意的问题,举例说明:
模块1:
#include <linux/module.h>
static int __init demo_init(void)
{
printk("module init\n");
printk("add(6,4)=%d\n",myadd(6,4));
return 0;
}
static void __exit demo_exit(void)
{
printk("module exit\n");
return 0;
}
module_init(demo_init);//入口函数
module_exit(demo_exit);//出口函数
MODULE_LICENSE("GPL");//GPL协议
模块2:
#include <linux/module.h>
int myadd(int a,int b)
{
return a+b;
}
static int __init math_init(void)
{
printk("math init\n");
return 0;
}
static void __exit math_exit(void)
{
printk("math exit\n");
return 0;
}
module_init(math_init);
module_exit(math_exit);
MODULE_LICENSE("GPL");
Makefile:
KERNELDIR=/lib/modules/$(shell uname -r)/build/
#KERNELDIR=~/kernel/linux-3.14
PWD=$(shell pwd)
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
obj-m +=math.o demo.o
如果直接make:
编译器未找到
WARNING: “mysub” [/mnt/hgfs/linux-3.14/zhoum-drivers/03-module-exportsymbols/demo.ko] undefined!
WARNING: “myadd” [/mnt/hgfs/linux-3.14/zhoum-drivers/03-module-exportsymbols/demo.ko] undefined!
直接加载:
insmod: ERROR: could not insert module demo.ko: Unknown symbol in module
问题: Unknown symbol in module
解决方案:
此问题多用在自定义的模块的函数引用或内核内部函数调用但未导出符号表;
无法找到模块函数的对应的符号表
首先需要在当前模块当中声明
extern int myadd(int x,int y);
然后需要依赖的模块的符号导出
vi Module.symvers
1 0xfc05b364 myadd …/math/math EXPORT_SYMBOL
导出的符号链接地址 名称 路径 声明
修改后模块1:
#include <linux/module.h>
extern int maadd(int a,int b);//声明
static int __init demo_init(void)
{
printk("module init\n");
printk("add(6,4)=%d\n",myadd(6,4));
return 0;
}
static void __exit demo_exit(void)
{
printk("module exit\n");
return 0;
}
module_init(demo_init);//入口函数
module_exit(demo_exit);//出口函数
MODULE_LICENSE("GPL");//GPL协议
模块2:
#include <linux/module.h>
int myadd(int a,int b)
{
return a+b;
}
EXPORT_SYMBOL(myadd);//需要依赖的模块的符号导出
static int __init math_init(void)
{
printk("math init\n");
return 0;
}
static void __exit math_exit(void)
{
printk("math exit\n");
return 0;
}
module_init(math_init);
module_exit(math_exit);
MODULE_LICENSE("GPL");
修改后直接加载模块:
$ sudo insmod demo.ko
报错:Unknown symbol in module-------------缺少依赖项
总结:
加载有顺序
先加载依赖,再加载模块
卸载也有顺序:
先卸载模块,再卸载依赖
【5】模块传参
首先介绍两个函数:
module_param(name, type, perm)
module_param_named(name, name, type, perm)
@name 合法参数—名字
@type 参数的类型
*Standard types are:
byte, short, ushort, int, uint, long, ulong
charp: a character pointer
bool: a bool, values 0/1, y/n, Y/N.
@perm 权限 ----0664 0644 rwx
6 4 4 5
rw- r-- rwx
r–
@perm is 0 if the the variable is not to appear in sysfs,
注: 模块传参要注意用户的权限—不想让应用层直接操作,只留给驱动去操作
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
int demoint=24;
char *demostr="chilei";
int a[5]={1,2,3,4,5};
module_param(demoint,int,0664);
module_param(demostr,charp,0664);
module_param_array(a,int,NULL,0);
static int __init demo_init(void)
{
int i=0;
printk("---%s---%d.\n",__func__,__LINE__);
printk("demoint=%d.\n",demoint);
printk("demostr=%s.\n",demostr);
for(i=0;i<5;i++)
{
printk("a[%d]=%d.\n",i,a[i]);
}
return 0;
}
static int __exit demo_exit(void)
{
printk("---%s---%d.\n",__func__,__LINE__);
}
module_init(demo_init);//入口函数
module_exit(demo_exit);//出口函数
MODULE_LICENSE("GPL");//GPL协议
注意:-----所有的变量的定义,必须放到最前面
测试:
总结:
1、模块传递int数据
module_param(demoint,int,0664);
模块传递字符串数据
module_param(demostr,charp,0664);
模块传递数组数据
基本:
module_param_array(a,int,NULL,0);