学习笔记三 :linux驱动之符号导出EXPORT_SYMBOL

符号导出EXPORT_SYMBOL

在写linux驱动程序的过程中遇到一个模块中编写的函数,或者变量需要在另一个模块中使用的时候就可以用符号导出EXPORT_SYMBOL。在Linux内核源码目录下有一个文件Module.symvers,该文件内就存放的linux内核中导出的符号。
内核目录下的符号表
下面的代码是使用方法,首先是模块A,模块A中有一个变量num,和一个函数print_hello需要在模块B中使用,所以需要将模块A中的这两个导出。

// 模块A
#include <linux/module.h>

static int num = 100;

static void print_hello(void)
{
    printk("hello\r\n");
}

static int __init symbol_init(void)
{
    printk("export symbol\r\n");
    return 0;
}

static void __exit symbol_exit(void)
{
    printk("exit\r\n");
}

module_init(symbol_init);
module_exit(symbol_exit);

EXPORT_SYMBOL(num);
EXPORT_SYMBOL(print_hello);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen");

模块A的Makefile

ifneq ($(KERNELRELEASE,))
	obj-m:=a.o
else
	KERNEL_DIR:=/lib/modules/$(shell uname -r)/build
	CURRENT_DIR:=$(shell pwd)
	ccflags-y:=-std=gnu99 -Wno-declaration-after-statement
all:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURRENT_DIR) modules
clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURRENT_DIR) clean
endif

接着是模块B的代码,首先在B模块编译之前,需要将模块A编译后目录下生成的的Module.symvers文件拷贝到模块B目录下,这样模块B中才能找到需要的模块A导出的符号。

// 模块B
#include <linux/module.h>

extern int num;
extern void print_hello(void);

static int __init use_init(void)
{
	print_hello();
	return 0;
}

static void __exit use_exit(void)
{
	printk("num = %d\r\n",num);
}

module_init(use_init);
module_exit(use_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen");

模块B的Makefile通模块A,只需改obj-m后面的名字。
接下来就是编译模块B。

这里一定要注意顺序,首先是先将模块A编译,因为模块A编译后目录下的Module.symvers文件中才有导出的符号,然后再将该文件拷贝到 模块B目录下,有这个文件后编译的模块B才不会报错。

接着就是加载模块,这里也一定要有顺序,应当先加载A模块再加载B模块,写在也是先写在B模块再写在A模块,顺序反了会报错的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值