Warning building a kernel module that uses exported symbols
This issue (and how to compile correctly in this case) is explained in http://www.kernel.org/doc/Documentation/kbuild/modules.txt
Sometimes, an external module uses exported symbols from another
external module. kbuild needs to have full knowledge of all symbols
to avoid spitting out warnings about undefined symbols. Three
solutions exist for this situation.NOTE: The method with a top-level kbuild file is recommended but may
be impractical in certain situations.Use a top-level kbuild file If you have two modules, foo.ko and
bar.ko, where foo.ko needs symbols from bar.ko, you can use a
common top-level kbuild file so both modules are compiled in the
same build. Consider the following directory layout:./foo/ <= contains foo.ko ./bar/ <= contains bar.ko
The top-level kbuild file would then look like:
#./Kbuild (or ./Makefile): obj-y := foo/ bar/
And executing
$ make -C $KDIR M=$PWD
will then do the expected and compile both modules with full
knowledge of symbols from either module.
Use an extra Module.symvers file When an external module is built,
a Module.symvers file is generated containing all exported symbols
which are not defined in the kernel. To get access to symbols from
bar.ko, copy the Module.symvers file from the compilation of bar.ko
to the directory where foo.ko is built. During the module build,
kbuild will read the Module.symvers file in the directory of the
external module, and when the build is finished, a new
Module.symvers file is created containing the sum of all symbols
defined and not part of the kernel.Use "make" variable KBUILD_EXTRA_SYMBOLS If it is impractical to
copy Module.symvers from another module, you can assign a space
separated list of files to KBUILD_EXTRA_SYMBOLS in your build file.
These files will be loaded by modpost during the initialization of
its symbol tables.
Building an out-of-tree Linux kernel modules which share object files with exported symbols
After some tinkering with Kbuild system I ended up with conclusion that a most straightforward way to handle situation like this, is to filter-out warning messages from make
output in the outer makefile:
$(MAKE) -C $(KDIR) M=$$PWD 2>&1 \
| grep -v '^WARNING:.*exported twice\. Previous export was in'
or w/o sacrificing STDERR and squashing it into STDOUT, but it requires bash
:
bash -c "$(MAKE) -C $(KDIR) M=$$PWD 2> >( grep -v '^WARNING:.*exported twice\. Previous export was in' )"
building kernel module and resolve missing symbol definitions
(If the symbols are not in /proc/kallsyms, it is likely that that the kernel source did not explicitly EXPORT_SYMBOL() those symbols. Hence, in order to use those symbols, you have several options:
1) Add EXPORT_SYMBOL() to each symbol in the source that your kmod needs
to link with, and then re-compile the kernel.
This option has several drawbacks. In my mind, the greatest drawback is that many distro's don't offer support for a recompiled kernel (re: SUSE SLES, etc.). Perhaps this solution would work for a one-off kmod. However, if you plan to distribute it to others, you will have to get a feel for how they take to the idea of recompiling their kernel.
2) Copy the entire function(s) from the kernel source into your code.
Of course, if the copied functions contain references to other kernel functions, which also lack EXPORT_SYMBOL() (and are not listed in /proc/kallsysm), this option isn't always helpful.
3) Find another Linux release, or distro, which exports the needed symbols.
I work a lot with SLES. I find that from one release to the next, kernel symbols come and go. There are also differences between SUSE, Redhat, etc., distros; where one may export the needed symbols.
How to call exported kernel module functions from another module?
From my research, it seems that those are the only three ways to handle this situation, and I've gotten each of them to work, so I think I'll just pick my favorite out of those.
EXPORT_SYMBOL in kernel module | undefined symbol during insmod
There are two ways to solve this, 1) Compile both the kernel modules in the same Makefile i.e. objs-m := a.o b.o. 2) Include **KBUILD_EXTRA_SYMBOLS=<"absolute path to the Module.symvers of the kernel module which is exporting function or variable"> in the Makefile of the kernel module which will use exported function or variable.
kernel symbol marked with T in /proc/kallsyms is not exported
Mark "T" in /proc/kallsyms
means that symbol is globally visible, and can be used in other kernel's code (e.g. by drivers, compiled built-in).
But for being usable in kernel module's code, symbol is needed to be exported using EXPORT_SYMBOL
or similar. List of exported symbols is maintained separately from list of all symbols in the kernel.
Exported symbols can be found in file /lib/modules/<kernel-version>/build/Module.symvers
.
(this file should exist for possibility to build kernel modules against given kernel).
Related Topics
A Running Bash Script Is Hung Somewhere. How to Find Out What Line It Is On
How Use Qt in Visual Studio Code
How to Convert Pptx Files to Jpg or Png (For Each Slide) on Linux
How to Enable Bash in Windows 10 Developer Preview
Using Jq to Fetch Key Value from JSON Output
Gcc Compilation "Cannot Compute Suffix of Object Files: Cannot Compile"
Linux Tool to Send Raw Data to a Tcp Server
Android Sdk on a 64-Bit Linux MAChine
How to Access an Environment Variable in a .Desktop File's Exec Line
Permissions Required to Move File to Different Directory in Unix/Linux
How to Query X11 Display Resolution
How to Add a Line to a File in a Shell Script
Does Gdb Temporarily Give Pages Write Permission
Why Doing I/O in Linux Is Uninterruptible
Does Kernel's Panic() Function Completely Freezes Every Other Process