6

I have a kernel module which has a structure like this:

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

I have created an array of instances of this struct as:

struct test foo[8];

I want to export this structure or the array "foo" using EXPORT_SYMBOL and access foo[0].a in other kernel module.

I tried EXPORT_SYMBOL(foo); from the provider module and extern struct test * foo; in the receiver module but I am unable to access the variable. Please point where am I making mistake.

Here is some more of the code:

Kernel Module 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");
}

Kerne Module 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");
}

Here is the header file with the structure definition:

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

#endif
iqstatic
  • 2,322
  • 3
  • 21
  • 39

3 Answers3

8

In module A You have taken as

struct test foo[8];

and made it as

EXPORT_SYMBOL(foo);

So to use it in another module B you need to add

extern struct test foo[8];

And make sure while using it in module B , module A should be loaded first.


If you do not want to export whole array but just want to export pointer then

In module a

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

In module B

extern struct *test temp;

and access memorys as temp[0].a


One more Example

see here 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);

So it is used as

281 extern struct snd_card *snd_cards[SNDRV_CARDS];

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


Final Update

#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");
}

Now moduel 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");
}

Header files.

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

#endif

Module 1 should be loaded first and then module 2 should be loded.

Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
  • Already tried, doesnt work. The module B throws error while compiling. **sample2.c:6: error: array type has incomplete element type** and i have already referred to the example you mentioned. – iqstatic Aug 22 '14 at 12:11
  • 1
    @iqstatic I think you should put defination of struct test { int a; int b; ..... } in header file and that header file should be included in both module's c files. It will remove compile time error – Jeegar Patel Aug 22 '14 at 12:18
  • I tried the changes you made in your answer. Still there are errors during compilation. I have worked with EXPORT_SYMBOL earlier where i exported an integer variable. There i didn't face any issue. I wonder why this is happening here. – iqstatic Aug 22 '14 at 12:37
  • I am just experimenting with these simple kernel modules. I will be having multiple kernel modules which will require this data centrally. I don't want to keep the copy of this header locally everywhere or provide a path to the header. – iqstatic Aug 22 '14 at 12:42
  • @@Mr.32 As suggested by you I tried putting the definition of the struct in a header and including in the modules's C files, that removed the compilation error but I still cannot access the value of 'a' in the other module. – iqstatic Aug 25 '14 at 09:16
  • @iqstatic Please put that code in your question so i can say anything about that... – Jeegar Patel Aug 25 '14 at 09:40
  • @iqstatic I have updated my answer with final update. If it works and you understand it then upvote it and accept my answer. – Jeegar Patel Aug 25 '14 at 12:39
  • @Mr32 I understand your solution but it doesn't work somehow. Upvoted for your efforts. – iqstatic Aug 26 '14 at 10:04
3

The answer given by Mr.32 somehow didn't solve my problem. So I implemented this without using a structure and created separate arrays for each of the members a,b,c in order to proceed with my task...

After doing a bit more experiments I was able to achieve the original requirement of exporting the structure.

I modified the header file as shown below:

#ifndef __TEST_CONFIG
#define __TEST_CONFIG

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

extern struct test foo[8];

#endif

After doing this I defined this structure in the provider module as:

struct test foo[8];
EXPORT_SYMBOL(foo);

And include the header and referenced to it in the receiver module as:

extern struct test foo[8];

By doing these changes I was able to access the values from first module in the second module by doing foo[0].a;.

Community
  • 1
  • 1
iqstatic
  • 2,322
  • 3
  • 21
  • 39
0

During kernel module compilation Module.symvers file is generated in the same directory (along with source files by default). If symbols are exported and imported in some different source with different directory then Module.symvers file needs to be copied to directory of other source files. Some times in order to have clean build these files are removed. If symbols are exported then deleting files will not resolve external symbols.