How to export a struct between two kernel modules using EXPORT_SYMBOL or equivalent?

11,281

Solution 1

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;.

Solution 2

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.

Share:
11,281
iqstatic
Author by

iqstatic

I am an enthusiast of Open source software, and know Linux quite well. One of my very favorite languages still is C, but when it comes to finding solutions I really don't care very much in which language they need to be achieved.

Updated on June 05, 2022

Comments

  • iqstatic
    iqstatic almost 2 years

    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
    iqstatic over 9 years
    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.
  • Jeegar Patel
    Jeegar Patel over 9 years
    @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
  • iqstatic
    iqstatic over 9 years
    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
    iqstatic over 9 years
    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
    iqstatic over 9 years
    @@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.
  • Jeegar Patel
    Jeegar Patel over 9 years
    @iqstatic Please put that code in your question so i can say anything about that...
  • Jeegar Patel
    Jeegar Patel over 9 years
    @iqstatic I have updated my answer with final update. If it works and you understand it then upvote it and accept my answer.
  • iqstatic
    iqstatic over 9 years
    @Mr32 I understand your solution but it doesn't work somehow. Upvoted for your efforts.