驱动-内核模块开发中的符号导出机制

提示: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 导入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值