c - 如何使用 EXPORT_SYMBOL 或等效项在两个内核模块之间导出结构?

标签 c struct linux-kernel kernel-module

我有一个内核模块,其结构如下:

struct test {
    int a;
    int b;
    .....
}

我已经创建了这个结构的一个实例数组:

struct test foo[8];

我想使用 EXPORT_SYMBOL 导出这个结构或数组“foo”,并在其他内核模块中访问 foo[0].a

我尝试了提供者模块中的 EXPORT_SYMBOL(foo); 和接收者模块中的 extern struct test * foo; 但我无法访问该变量。请指出我哪里出错了。

下面是一些代码:

内核模块 1:

#include <....>
#include "test_config.h"
....
MODULE_LICENSE("GPL");

struct test {
int a;
int b;
.....
}

test_t foo[8];
//EXPORT_SYMBOL(foo);

/*Code to create sysctl variables out of these members of the struct test*/

int init_module(void)
{
    printk(KERN_INFO "Hello World\n");
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye Cruel World\n");
}

内核模块 2:

#include <linux/module.h>
#include <linux/kernel.h>
#include "test_config.h"

int init_module(void)
{
    test_t foo[8];
    printk ("Value of foo is :: %d\n", foo[0].a);
    foo[0].a++;
    printk(KERN_INFO "Hello Again World\n");
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye Again Cruel World\n");
}

这是带有结构定义的头文件:

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

typedef struct test
{
    int a;
    int b
    int c;
    int d;
    float e;
}test_t;

#endif

最佳答案

模块A中,您已将其视为

struct test foo[8];

并把它变成

EXPORT_SYMBOL(foo);

所以要在另一个模块B中使用它,您需要添加

extern struct test foo[8];

并确保在模块 B 中使用它时,应首先加载模块 A。


如果你不想导出整个数组而只想导出指针,那么

在模块a中

struct test foo[8];
struct *test temp = &foo(0);
EXPORT_SYMBOL(temp);

在模块B中

extern struct *test temp;

并以 temp[0].a 的形式访问内存


再举一个例子

看这里http://lxr.free-electrons.com/source/sound/core/init.c?v=2.6.35;a=arm#L48

 48 struct snd_card *snd_cards[SNDRV_CARDS];
 49 EXPORT_SYMBOL(snd_cards);

所以它被用作

281 extern struct snd_card *snd_cards[SNDRV_CARDS];

http://lxr.free-electrons.com/source/include/sound/core.h?v=2.6.35#L281


最终更新

#include <....>
#include "test_config.h"
....
MODULE_LICENSE("GPL");


test_t foo[8];
EXPORT_SYMBOL(foo);


int init_module(void)
{
    printk(KERN_INFO "Hello World\n");
    foo[0].a = 10;  // set some value.
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye Cruel World\n");
}

现在是模块 2

#include <linux/module.h>
#include <linux/kernel.h>
#include "test_config.h"

extern test_t foo[8];

int init_module(void)
{
    printk ("Value of foo is :: %d\n", foo[0].a); // it should print 10
    printk(KERN_INFO "Hello Again World\n");
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye Again Cruel World\n");
}

头文件。

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

typedef struct test
{
    int a;
    int b
    int c;
    int d;
    float e;
}test_t;

#endif

应先加载模块 1,然后再加载模块 2。

关于c - 如何使用 EXPORT_SYMBOL 或等效项在两个内核模块之间导出结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25446203/

相关文章:

linux - fsnotify 真的需要全局列表扫描吗?

c++ - C/++函数如何正确返回值?

c - 在 C 中填充动态结构数组

c - c中的通用数据结构搜索

c++ - 无法编译(未声明且预期的主表达式)

c - 使用结构类型数组进行结构黑客

c - udp 套接字 - 绑定(bind)和连接成功,但发送不起作用

c - 获取 C 中结构体的大小

linux - 如何使用 GDB 和 QEMU 调试 Linux 内核?

c - 文件描述符中实际存储了多少信息?