linux 内核模块 gpl,Linux内核模块EXPORT_SYMBOL和EXPORT_SYMBOL_GPL使用说明

EXPORT_SYMBOL(符号名);

EXPORT_SYMBOL_GPL(符号名);

EXPORT_SYMBOL 和 EXPORT_SYMBOL_GPL 用于导出符号到内核符号表中(内核符号表可通过 ‘/proc/kallsyms’ 查看),导出的符号可以被其它模块调用,调用前需要先声明。

通过 EXPORT_SYMBOL 导出的符号可以被包含GPL许可权的模块和不包含GPL许可权的模块调用;

通过 EXPORT_SYMBOL_GPL 导出的符号只能被包含GPL许可权的模块调用,否则会报错 FATAL: modpost: GPL-incompatible module ***.ko uses GPL-only symbol '***'.

example:模块A导出符号,模块B使用符号,代码如下

A模块代码:

// A module

#include

#include

int add_integar(int a, int b)

{

return a + b;

}

EXPORT_SYMBOL(add_integar);

int sub_integar(int a, int b)

{

return a - b;

}

EXPORT_SYMBOL_GPL(sub_integar);

static int __init A_init(void)

{

printk(KERN_INFO "A enter\n");

return 0;

}

static void __exit A_exit(void)

{

printk(KERN_INFO "A exit\n");

}

module_init(A_init);

module_exit(A_exit);

MODULE_AUTHOR("TASK_RUNNING.\n");

MODULE_LICENSE("GPL v2");

MODULE_DESCRIPTION("export symbol module.\n");

A模块makefile:

#A module makefile

KVERS = $(shell uname -r)

obj-m += A.o

build: kernel_modules

kernel_modules:

make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:

make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

A模块编译后,会生成Module.symvers文件,使用 cat Module.symvers可查看内容如下:

0x00000000 sub_integar /home/task_running/test/A/A EXPORT_SYMBOL_GPL

0x00000000 add_integar /home/task_running/test/A/A EXPORT_SYMBOL

当加载A模块时,符号会被导出到内核符号表,使用 grep integar /proc/kallsyms 可查看被导出的符号,使用root权限执行时,可以查看符号对应的地址,普通用户查看的地址为全0

0000000000000000 r __ksymtab_add_integar [A]

0000000000000000 r __kstrtab_add_integar [A]

0000000000000000 r __ksymtab_sub_integar [A]

0000000000000000 r __kstrtab_sub_integar [A]

0000000000000000 T add_integar [A]

0000000000000000 t sub_integar [A]

B模块代码:

// B module

#include

#include

//此处需要用extern声明外部符号

extern int add_integar(int a, int b);

extern int sub_integar(int a, int b);

static int __init B_init(void)

{

printk(KERN_INFO "B module enter\n");

printk(KERN_INFO "ADD = %d\n", add_integar(5, 6));

printk(KERN_INFO "SUB = %d\n", sub_integar(6, 5));

return 0;

}

static void __exit B_exit(void)

{

printk(KERN_INFO "B module exit\n");

}

module_init(B_init);

module_exit(B_exit);

MODULE_AUTHOR("TASK_RUNNING.\n");

MODULE_LICENSE("GPL v2");

MODULE_DESCRIPTION("use symbol module.\n");

B模块makefile:

#B module makefile

KVERS = $(shell uname -r)

obj-m += B.o

build:kernel_modules

#此处需要指定A模块编译后生成的Module.symvers文件

KBUILD_EXTRA_SYMBOLS += /home/task_running/test/A/Module.symvers

export KBUILD_EXTRA_SYMBOLS

kernel_modules:

make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

clean:

make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

B模块必须在A模块加载后才能使用A模块的符号,加载B模块后,使用 dmesg 可以查看内核打印的信息。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值