第四章Linux内核模块之六(导出符号)

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 "[email protected]"
#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]

猜你喜欢

转载自blog.csdn.net/xiezhi123456/article/details/80312569