如何使用EXPORT_SYMBOL或等效的方法在两个内核模块之间导出结构?

iqs*_*tic 5 c struct kernel-module linux-kernel

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

struct test {
    int a;
    int b;
    .....
}
Run Code Online (Sandbox Code Playgroud)

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

struct test foo[8];
Run Code Online (Sandbox Code Playgroud)

我想在其他内核模块中使用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");
}
Run Code Online (Sandbox Code Playgroud)

Kerne模块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");
}
Run Code Online (Sandbox Code Playgroud)

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

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

#endif
Run Code Online (Sandbox Code Playgroud)

Jee*_*tel 8

模块A中你已经采取了

struct test foo[8];
Run Code Online (Sandbox Code Playgroud)

并使其成为

EXPORT_SYMBOL(foo);
Run Code Online (Sandbox Code Playgroud)

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

extern struct test foo[8];
Run Code Online (Sandbox Code Playgroud)

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


如果你不想导出整个数组但只想导出指针

在模块中

struct test foo[8];
struct *test temp = &foo(0);
EXPORT_SYMBOL(temp);
Run Code Online (Sandbox Code Playgroud)

在模块B中

extern struct *test temp;
Run Code Online (Sandbox Code Playgroud)

和访问记忆为 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);
Run Code Online (Sandbox Code Playgroud)

因此它被用作

281 extern struct snd_card *snd_cards[SNDRV_CARDS];
Run Code Online (Sandbox Code Playgroud)

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");
}
Run Code Online (Sandbox Code Playgroud)

现在模块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");
}
Run Code Online (Sandbox Code Playgroud)

头文件.

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

#endif
Run Code Online (Sandbox Code Playgroud)

应首先加载模块1,然后对模块2进行加密.


iqs*_*tic 3

32先生给出的答案不知怎的并没有解决我的问题。因此,我在不使用结构的情况下实现了这一点,并为每个成员 a、b、c 创建了单独的数组,以便继续执行我的任务......

经过更多的实验,我能够实现导出结构的原始要求。

我修改了头文件如下所示:

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

extern struct test foo[8];

#endif
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我在提供程序模块中将此结构定义为:

struct test foo[8];
EXPORT_SYMBOL(foo);
Run Code Online (Sandbox Code Playgroud)

并包含标头并在接收器模块中引用它,如下所示:

extern struct test foo[8];
Run Code Online (Sandbox Code Playgroud)

通过进行这些更改,我能够通过执行以下操作来访问第二个模块中第一个模块的值foo[0].a;