Linux驱动开发 ---- 内核模块开发(下)

【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);

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值