linux驱动开发LDD(二)——符号导出和模块参数

(一)导出符号

它是用于解决模块之间的相互函数调用问题
 
export.c

#include <linux/init.h>
#include <linux/module.h>

int my_add(int x, int y)
{
    printk("<1>"  "enter %s\n", __func__);

    return x+y;
}
EXPORT_SYMBOL(my_add);//EXPORT_SYMBOL_GPL(my_add);

 
import.c

#include <linux/init.h>
#include <linux/module.h>

extern int my_add(int, int);
static int __init import_init(void)
{
    int res = 0;

    res = my_add(10,20);
    printk("<1>"  "res=%d\n", res);
    return 0;
}
static void __exit import_exit(void)
{
    printk("<1>"  "enter %s\n", __func__);
}
module_init(import_init);
module_exit(import_exit);

 
Makefile

KERNEL=/home/cjl/driver/kernel/

obj-m += export.o
obj-m += import.o

all:
	make -C $(KERNEL)  M=$(PWD)  modules
	cp *.ko /home/cjl/driver/rootfs/
clean:
	make -C $(KERNEL)  M=$(PWD) clean

编译完成后,Makefile中自动将*.ko 复制到了网络根文件系统中,在下位机执行如下
在这里插入图片描述
1)如果xxx_func没有被EXPORT_SYMBOL导出
其它模块中是不能使用该函数的
2)被EXPORT_SYMBOL导出的函数可以遵循GPL
的模块使用,也可以被不遵循GPL的模块使用
3)被EXPORT_SYMBOL_GPL导出的函数
只能被那些遵循GPL的模块所使用

(二)导出符号,生成1个.ko文件

将(一)中Makefile改为
 
Makefile

KERNEL=/home/cjl/driver/kernel/

obj-m += im.o
im-objs := import.o export.o

all:
	make -C $(KERNEL)  M=$(PWD)  modules
	cp *.ko /home/cjl/driver/rootfs/
clean:
	make -C $(KERNEL)  M=$(PWD) clean

执行make,生成im.ko,在下位机安装效果为
在这里插入图片描述

注意:
若是export.c中本身就有module_init()和module_exit()修饰的函数的话,需要将其取消,并且删除函数定义时的__init和__exit,然后将这两个函数也导出符号,在import.c的__init 和__exit函数中合适的位置,调用原来export.c在安装和卸载时需要调用的函数。
Makefile释义:obj-m += im.o指定了生成的.ko的名字,im-objs :=指明了依赖,固定格式为obj-m += xxx.o xxx-objs := yyy.o zzz.o 注意xxx不可和依赖重名,如,obj-m += hello.o hello-objs := hello.o world.o,hello与hello重名

(三) 模块参数
  1. 将需要的参数定义为全局变量

  2. 通过module_param或者module_param_array将定义的全局变量声明为模块参数
    module_param(name,type,perm)
    name, 变量名称
    type, 变量的数据类型 支持的类型 int short long charp
    perm, 权限,如0644
     
    module_param_array(name,type,nump,perm);
    将数组声明为模块参数
    name, 数组名
    type, 数组中成员变量的类型
    nump, 数组元素个数指针
    perm, 权限

     
    moduleparam.c

    #include <linux/init.h>
    #include <linux/module.h>
    
    int irq = 0;
    char *str = "hello world\n";
    int fish[10] = {0};
    int num = 10;
    module_param(irq, int, 0644);
    module_param(str, charp, 0);
    module_param_array(fish, int, &num, 0600);
    
    int __init moduleparam_init(void)
    {
        int i = 0;
    
        printk("<1>" "irq=%d\n", irq);
        printk("<1>" "str=%s\n", str);
        for(; i<num; i++)
        {
            printk("<1>" "fish[%d]=%d\n", i, fish[i]);
        }
        return 0;
    }
    void __exit moduleparam_exit(void)
    {
        int i = 0;
    
        printk("<1>" "irq=%d\n", irq);
        printk("<1>" "str=%s\n", str);
        for(; i<num; i++)
        {
            printk("<1>" "fish[%d]=%d\n", i, fish[i]);
        }
    }
    module_init(moduleparam_init);
    module_exit(moduleparam_exit);
    

     
    Makefile

    KERNEL=/home/cjl/driver/kernel/
    
    obj-m += moduleparam.o
    
    all:
    	make -C $(KERNEL)  M=$(PWD)  modules
    clean:
    	make -C $(KERNEL)  M=$(PWD) clean
    

    执行make生成.ko文件,下位机执行效果如下
    在这里插入图片描述

    可以带参数安装模块,如下,数组大小也根据传参个数变了
    在这里插入图片描述紧接上步,模块安装完后,会在/sys/module/目录下生成一个模块名文件夹,该例中为moduleparam, 在/sys/module/moduleparam/parameters/目录下用cat命令查看模块参数的值,也可以通过echo命令向里边写值以便达到更改参数的目的,参数更改后,可以看到,在卸载模块时,参数的值变了
    在这里插入图片描述其中,更改str时找不到文件是因为其权限为0,任何用户不可见该文件
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值