4.6 导出符号
Linux的“/proc/kallsyms”文件对应着内核符号表,它记录了符号以及符号所在的内存地址。模块可以使用如下宏导出符号到内核符号表中:
EXPORT_SYMBOL(符号名);
EXPORT_SYMBOL_GPL(符号名);
导出的符号可以被其他模块使用,只需使用前声明一下即可。EXPORT_SYMBOL_GPL()只适用于包含GPL许可权的模块。
代码清单4.5给出了一个导出整数加、减运算函数符号的内核模块的例子。
代码清单4.5 内核模块中的符号导出
1、one.c
#include <linux/init.h>
#include <linux/module.h>
int add_integar(int a, int b)
{
return a + b;
}
EXPORT_SYMBOL_GPL(add_integar);
int sub_integar(int a, int b)
{
return a - b;
}
EXPORT_SYMBOL_GPL(sub_integar);
static int __init hello_init(void)
{
printk(KERN_INFO "one Hello world!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "one hello exit!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL v2");
2、hello_world.c
#include <linux/init.h>
#include <linux/module.h> // module.h:17:#include <linux/moduleparam.h> 间接包含头文件
#define DRIVER_AUTHOR "xz@vi-chip.com.cn"
#define DRIVER_DESC "A sample driver"
extern int add_integar(int a, int b); // 导出符号函数外部声明
extern int sub_integar(int a, int b);
static int __init hello_init(void)
{
int a = 5;
int b = 3;
int result = -1;
printk(KERN_INFO "vichip hello_init\n");
result = add_integar(a, b);
printk(KERN_INFO "vichip hello_init add_integar result = %d.\n", result);
result = sub_integar(a, b);
printk(KERN_INFO "vichip hello_init sub_integar result = %d.\n", result);
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "vichip hello_exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_VERSION("v1.0");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_ALIAS(DRIVER_DESC);
3、Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
else
obj-m := hello_world.o one.o
endif
4、安装内核模块(hello_world内核模块依赖于one)
sudo insmod one.ko
sudo insmod hello_world.ko
5、查看消息
dmesg
[31987.903552] one Hello world!
[32013.762973] vichip hello_init
[32013.762978] vichip hello_init add_integar result = 8.
[32013.762980] vichip hello_init sub_integar result = 2.
6、卸载内核模块hello_world内核模块依赖于one)
sudo rmmod hello_world
sudo rmmod one
7、查看消息
dmesg
[32149.329751] vichip hello_exit
[32154.618282] one hello exit!
8、查看内核符号表
安装内核模块sudo insmod one.ko
grep integar /proc/kallsyms
0000000000000000 r __kstrtab_sub_integar [one]
0000000000000000 r __kcrctab_sub_integar [one]
0000000000000000 r __kstrtab_add_integar [one]
0000000000000000 r __kcrctab_add_integar [one]
0000000000000000 t add_integar [one]
0000000000000000 r __ksymtab_add_integar [one]
0000000000000000 t sub_integar [one]
0000000000000000 r __ksymtab_sub_integar [one]