from here
48 struct snd_card *snd_cards[SNDRV_CARDS]; 49 EXPORT_SYMBOL(snd_cards);
I am not getting whats the meaning of it and why that is used. I tried to search about it but not understanding the meaning of that.
During a kernel build, a file named Module. symvers will be generated. Module. symvers contains all exported symbols from the kernel and compiled modules. For each symbol, the corresponding CRC value is also stored.
Linux Kernel Modules. Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. A module can be configured as built-in or loadable.
It makes a symbol accessible to dynamically loaded modules (provided that said modules add an extern
declaration).
Not long ago, someone asked how to use it.
Here is a good explanation.
https://www.quora.com/What-is-the-difference-between-extern-and-EXPORT_SYMBOL-in-Linux-kernel-codes
Extern is a C storage class keyword. In the kernel, as in any other C code, it tells the compiler that the definition of the variable or function it qualifies is implemented in another “file”, or rather, more accurately Translation unit (programming) - Wikipedia. The translation unit that does define it should not use the static qualifier. Therefore, the symbol table has an entry corresponding to it. At link time, the symbol is resolved as normal. There is nothing kernel specific about “extern”.
EXPORT_SYMBOL() is a macro the Linux kernel headers define. It has not much in common with extern. It tells the kbuild mechanism that the symbol referred to should be part of the global list of kernel symbols. That, in turn allows kernel modules to access them. Code that is built into the kernel itself (as opposed to a module) can, of course, access any non-static symbol via an extern declaration, in accordance with regular C. The EXPORT_SYMBOL() mechanism allows us to export a symbol for use by loadable modules as well. An interesting thing is that a symbol thus exported by one module becomes accessible to another module that may depend on it!
To summarise, extern is not kernel specific. It is used to qualify a declaration to a non-static symbol from another translation unit. EXPORT_SYMBOL() is specific to the Linux kernel. It is used in the translation unit of the definition to make the symbol available to loadable modules.
So EXPORT_SYMBOL is just a mechanism like extern, but it's for reference between loadable modules not file.
To move forwards, we can guess it's achived by the extern because extern is form C which is the foundation.
Here is a clue.
https://elixir.bootlin.com/linux/v4.6.7/source/include/linux/export.h#L56
#define EXPORT_SYMBOL(sym) \ __EXPORT_SYMBOL(sym, "") /* For every exported symbol, place a struct in the __ksymtab section */ #define __EXPORT_SYMBOL(sym, sec) \ extern typeof(sym) sym; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] __attribute__((section("__ksymtab_strings"), aligned(1))) = VMLINUX_SYMBOL_STR(sym); \ extern const struct kernel_symbol __ksymtab_##sym; \ __visible const struct kernel_symbol __ksymtab_##sym __used __attribute__((section("___ksymtab" sec "+" #sym), unused)) = { (unsigned long)&sym, __kstrtab_##sym }
First declare a extern sym.
Then a string __kstrtab_##sym = = VMLINUX_SYMBOL_STR(sym).
Last a extern struct kernel_symbol __ksymtab_##sym = { (unsigned long)&sym, __kstrtab_##sym }. &sym record the real address of the sym such as a function or variable, _kstrtab##sym record the name string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With