What is EXPORT_SYMBOL_GPL in Linux kernel code?
It is macro to define some symbol (e.g. function) as exportable (seen from kernel loadable modules). If the symbol has no "EXPORT_SYMBOL", it will be not accessible from modules.
EXPORT_SYMBOL_GPL
will show the symbol only in GPL-licensed modules, and EXPORT_SYMBOL
- in modules with any license.
http://lwn.net/Articles/154602/ - On the value of EXPORT_SYMBOL_GPL (2005, corbet)
When a loadable module is inserted, any references it makes to kernel functions and data structures must be linked to the current running kernel. The module loader does not provide access to all kernel symbols, however; only those which have been explicitly exported are available.
Exports come in two flavors: vanilla (EXPORT_SYMBOL) and GPL-only (EXPORT_SYMBOL_GPL). The former are available to any kernel module, while the latter cannot be used by any modules which do not carry a GPL-compatible license.
Kernel module using exported symbols depending on which other module is loaded
You can achieve this by not using exported symbols directly, but by looking for them in the runtime using kallsyms_lookup_name()
. That way your module X will not have explicit dependencies on symbols exported by modules Y1 and Y2, so it will be able to load even if one (or even both) of those modules are not loaded.
This also means that your module will be responsible for checking that all the symbols required for its operation are present. It will also need to manually increment refcount for modules providing those symbols via try_module_get()
, and then decrement it on module exit via module_put()
.
how to define linux kernel variable accessed by several source file?
When you use want to use a global variable in kernel modules, you should use the EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() or EXPORT_SYMBOL_GPL_FUTURE():
Eg:
int myvar;
EXPORT_SYMBOL(myvar);
you should then use
extern int myvar
in the other file where you want to use it, before you use it.
Unknown symbol shown when 'insmod' module1 calls function declared in module2
I found the solution from an old post:
insmod fails with "Unknown symbol in module" for a symbol defined in another module
Turns out 2 modules need to be built at the same time. I built they separately with 2 different Makefile.
Unknown symbol when loading a kernel module
This may actually be related to the module license! If you look at the kernel source code, the function power_supply_get_by_name
is exported here. You can see it's using EXPORT_SYMBOL_GPL
. As this answer explains:
EXPORT_SYMBOL_GPL will show the symbol only in GPL-licensed modules
The use of this macro is controversial, but that's the way the project operates... To gain access to the symbols you need, you'll need to license your module as GPL:
MODULE_LICENSE("GPL");
Can kernel module use kernel data structures?
Yes, after including corresponding header, kernel module can use anything that is defined in that header: data structures, macros, static inline functions...
As for functions, declared in the header file and implemented in kernel's source file, only those which are exported using EXPORT_SYMBOL/EXPORT_SYMBOL_GPL can be used in modules.
Related Topics
Get Lines of File1 Which Are Not in File2
Switch/Case Doesn't Work in Awk
Where Are Ioctl Parameters (Such as 0X1268/Blksszget) Actually Specified
Tomcat 7 with Java 8 on Windows and Linux
Debugging Shared Libraries with Gdbserver
How to Rebuild Rootfs in Buildroot
Sub-Shell Differences Between Bash and Ksh
Can Ptrace Tell If an X86 System Call Used the 64-Bit or 32-Bit Abi
How to Execute Parallel "For" Loops in Bash
How Much Does Using Htaccess Files Slow Down Website Performance (Especially with Solid State Disks)
Force Gnu Linker to Generate 32 Bit Elf Executables
How to Compile Glibc 32Bit on an X86_64 MAChine
Docker Behind Proxy That Changes Ssl Certificate
What Scheduling Algorithms Does Linux Kernel Use
Pycharm Startup Error: Unable to Detect Graphics Environment