提示:Linux内核模块开发中的符号导出机制,理解如何在内核模块之间共享函数和变量。
文章目录
实验目的
学习Linux内核模块开发中的符号导出机制,理解如何在内核模块之间共享函数和变量。
实验原理
在Linux内核模块开发中,一个模块可以使用另一个模块中的函数或变量,这需要通过符号导出机制实现:
-
EXPORT_SYMBOL() - 导出符号,可以被任何模块使用
-
EXPORT_SYMBOL_GPL() - 导出符号,但只能被GPL兼容的模块使用
导出的符号会被放入内核符号表中,其他模块可以通过extern声明来使用这些符号。
个人理解
承接上文内核传参实验,在命令行进行传参实验。那么实际中驱动程序就像我们平常写的代码一样,程序之间是存在共享变量和共享函数的。
那么如何让一个驱动程序的代码在另外一个驱动程序中直接使用,这就是内核模块符号导出的意思。
具体实验
既然是驱动程序之间的引用和共享,那么就涉及到多个程序,这里举例一个程序的变量和函数被导出给另外一个程序使用
共享模块程序-导出符号的模块
mathmodule.c 程序
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
// 共享变量
int shared_value = 100;
// 导出共享变量
EXPORT_SYMBOL(shared_value);
// 加法函数
int export_add(int a, int b)
{
return a + b;
}
EXPORT_SYMBOL(export_add);
// 减法函数
int export_sub(int a, int b)
{
return a - b;
}
EXPORT_SYMBOL(export_sub);
// 模块初始化
static int __init math_export_init(void)
{
printk(KERN_INFO "Math Export Module Loaded\n");
printk(KERN_INFO "Initial shared_value = %d\n", shared_value);
return 0;
}
导出符号EXPORT_SYMBOL
如实验原理描述所说,这里用到了导出符号函数,可以理解为标识符、方法。
如果想要模块中的变量被其它任意模块所使用,那么在定义变量和函数后,一定要将函数和变量 导出出去。如上面demo 源码描述的:
// 导出共享变量
EXPORT_SYMBOL(shared_value);
EXPORT_SYMBOL(export_add);
EXPORT_SYMBOL(export_sub);
使用导出符号的模块
hello.c 程序
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
// 声明外部符号
extern int shared_value;
extern int export_add(int a, int b);
extern int export_sub(int a, int b);
// 模块初始化
static int __init math_import_init(void)
{
int a = 30, b = 10;
printk(KERN_INFO "Math Import Module Loaded\n");
// 使用共享变量
printk(KERN_INFO "Original shared_value = %d\n", shared_value);
shared_value += 50;
printk(KERN_INFO "Modified shared_value = %d\n", shared_value);
// 使用加减函数
printk(KERN_INFO "%d + %d = %d\n", a, b, export_add(a, b));
printk(KERN_INFO "%d - %d = %d\n", a, b, export_sub(a, b));
return 0;
}
// 模块退出
static void __exit math_import_exit(void)
{
printk(KERN_INFO "Math Import Module Unloaded\n");
printk(KERN_INFO "Final shared_value = %d\n", shared_value);
}
module_init(math_import_init);
module_exit(math_import_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Demonstration of module_param_array usage");
导出其它模块共享的符号extern
其它模块共享的 符号:共享变量和函数,如果需要使用,那么就像头文件一样,需要先引入、导入进来。 就需要用到符号 extern 这个关键字。
如上源码测试程序 hello.c
// 声明外部符号
extern int shared_value;
extern int export_add(int a, int b);
extern int export_sub(int a, int b);
Makefile 文件编写
#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += mathmodule.o
obj-m += hello.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
执行编译脚本进行编译
make
生成:mathmodule.ko 和 hello.ko
加载驱动实验 insmod - dmesg
[root@topeet:/mnt/sdcard]# insmod mathmodule.ko
[root@topeet:/mnt/sdcard]# insmod hello.ko
结果如下:
总结
- 如何实现模块之间变量和函数的共享传递,用到EXPORT_SYMBOL 导入、extern 导入