I am coding outside the kernel source tree. There are two modules, the first one printt have a function printtty() to print string to the current tty, and the second module hello which invokes printtty() during initialization.
I have added EXPORT_SYMBOL(printtty) in module printt, and after insmod ./printt.ko, the information of printtty() can be seen in /proc/kallsyms.
The make process of module hello goes all right. But insmod ./hello.ko will cause an error like:
insmod: ERROR: could not insert module hello.ko: Invalid parameters
and dmesg shows
hello: no symbol version for printtty
hello: Unknown symbol printtty (err -22)`.
I've fixed this by
(1) Copy the .ko file to a location beneath /lib/modules/version/kernel
(2) Add the exported symbols to /lib/modules/version/build/Module.symvers
But I wonder is there any way to export a symbol just from an external module(without modifying kernel source tree)?
Add this line at the very top of your Makefile for your hello module:
KBUILD_EXTRA_SYMBOLS := /home/your-user/path/to/printt/Module.symvers
(be sure to put in the correct path to your printt module).
Now rebuild your hello module and it will be loaded just fine.
For details see Documentation/kbuild/modules.txt, "6.3 Symbols From Another External Module".
Related
Currently, I am working on programming Embedded C in Linux environment. I am trying to read input data from a joystick.
Before, when I created a header file joystick.h with all definitions and I initialized the joystick inside the main function (the header file is not compiled). Everything was okay and smooth.
However, when I refactored the code by putting initialization in joystick.c (which included joystick.h) and call the initialization function in main() from joystick.h. There was an error "fatal error: asm/types.h: No such file or directory". This error happened after creating joystick.c file because the joystick.c was added to Makefile to compile.
I tried several ways to fix this such as:
add "export ARCH=x86_64"
change asm -> asm-generic
Those did not work.
So how can I fix this error?
Best regards, Huy Nguyen.
This question already has answers here:
Building a kernel module from several source files which one of them has the same name as the module
(6 answers)
Closed 1 year ago.
I'm trying to build a loadable kernel module that includes another source file. I have the following in a Makefile or Kbuild file:
obj-m += mymodule.o
mymodule-y += other_src_file.o
In this scenario, other_src_file.c will be compiled. Strangely, the main source file mymodule.c will not be compiled. Intentional syntax errors are not caught. An object file mymodule.o is still produced, as is the .KO file. Loading this module on the target platform has no effect.
If I instead remove the second line in the Makefile/Kbuild that includes the other source file, my intentional syntax errors are caught. In a minimal example, init_module() will run and dmesg shows what I put into printk. It would not print anything prior to removing the line with other_src_file.o, despite being unchanged.
So what I find is that by including an additional source file (whether it is being used or not), the main module/C file is effectively ignored. An LKM is produced, but it has no effect from what I can see. Using --debug confirms in the latter case that mymodule.c is used (pipe into grep returns literally anything) whereas the former shows that there is not a single reference to mymodule.c (but many to other_src_file.c)
I've also tried setting up the makefile as the following, but there's no behavioral difference.
obj-m += mymodule.o
mymodule-y += other_src_file.o
all:
make -C ../../../ M=($PWD) modules # -C points to the root of my kernel
clean:
clean -c ../../../ M=$(PWD) clean
The output of make looks like the following:
LD some/path/mymodule/built-in.o
CC[M] /some/path/mymodule/other_src_file.o <-- notice it's the only CC; nothing for mymodule.o
LD[M] /some/path/mymodule/mymodule.o
Building modules, stage 2
MODPOST 1 modules
CC /some/path/mymodule/mymodule.mod.o
LD[M] /some/path/mymodule/mymodule.ko
When that other src file is left out, there is a line that shows mymodule.o being compiled.
I'm running in an Ubuntu 20.04 (VM) on x86_64. The kernel is 3.1.10, make is 4.2.1.
I feel like I'm missing something simple (unfamiliar with linux building, fairly familiar with C and compiling otherwise). Would greatly appreciate a pointer here.
The line
obj-m += mymodule.o
tells KBuild system just to build a module named mymodule.
The sources compiled into that module depend from variable mymodule-y:
If the variable is set (like in your code), then source list it taken only from this variable. There is no "automatic" addition of mymodule.c source.
If the variable is not set, then, by default, the module is compiled from the source which has the same name.
Note, that one cannot build a module mymodule from several sources, one of which is mymodule.c, that is has the same name as the module itself.
Either module or the source file should be renamed. That situation is described in that question.
This question is about linux kernel 4.10.
Loading an out-of-tree LKM causes kernel to print a warning:
module: loading out-of-tree module taints kernel.
This raises from this check in module.c:
if (!get_modinfo(info, "intree")) {
Reading get_modinfo it seams that "intree" is just a a magic-string livnig inside the .ko file.
Running readelf on a random LKM I found in my system shows this:
readelf -a imon.ko | grep intree
161: 00000000000006c0 9 OBJECT LOCAL DEFAULT 13 __UNIQUE_ID_intree1
While looking for intree in a simple, custom hello_world LKM returns no results.
Is this actually the case?
How are some modules marked as being in-tree? Is it done by adding a macro to the module (like MODULE_LICENCE), or by building the module in a specific way or something else?
In short, the build system contrives to add the line MODULE_INFO(intree, "Y"); to the "modulename.mod.c" file if and only if the module is being built intree.
There is an obvious way to fool the system by adding that line to one of your module's regular ".c" files, but I'm not sure why you'd want to.
Longer version....
External modules are normally built with a command similar to this:
$ make M=`pwd` modules
or the old syntax:
$ make SUBDIRS=`pwd` modules
The presence of a non-empty M or SUBDIRS causes the kernel's top-level "Makefile" to set the KBUILD_EXTMOD variable. It won't be set for a normal kernel build.
For stage 2 of module building (when the message "Building modules, stage 2" is output), make runs the "scripts/Makefile.modpost" makefile. That runs scripts/mod/modpost with different options when KBUILD_EXTMOD is set. In particular, the -I option is used when KBUILD_EXTMOD is set.
Looking at the source for modpost in "scripts/mod/modpost.c", the external_module variable has an initial value of 0, but the -I option sets it to 1. The function add_intree_flag() is called with the second parameter is_intree set to !external_module. The add_intree_flag() function writes MODULE_INFO(intree, "Y"); to the "modulename.mod.c" file if and only if its is_intree parameter is true.
So the difference between intree modules and external modules is the presence of the MODULE_INFO(intree, "Y"); macro call in the "modulename.mod.c" file. This gets compiled to "modulename.mod.o" and linked with the module's other object files to form the "modulename.ko" file.
In short: on Visual C++ 2015, I get a linker error complaining about the absence of symbols that are present in the .lib file I link against.
In long: While compiling-and-liking some program from the command line with cl.exe I get the following as the first of many errors:
main.obj : error LNK2001: unresolved external symbol "protected: static struct wxEventTable const wxApp::sm_eventTable" (?sm_eventTable#wxApp##1UwxEventTable##B)
AFAIK, this long line says that my main.obj refers to a function to which a symbol ?sm_eventTable#wxApp##1UwxEventTable##B is associated, but that the linker could not find this symbol in the (long) list of libs that I provided on the command line.
I compile in /MD mode. Don't know if it helps, hurts, or has no importance here.
One of the files I link with is wxmsw31u_core.lib and doing
dumpbin /headers wxmsw31u_core.lib > here.txt
gives a long file containting the following
Version : 0
Machine : 8664 (x64)
TimeDateStamp: 56D46194 Mon Feb 29 16:19:48 2016
SizeOfData : 00000045
DLL name : wxmsw310u_core_vc140_x64.dll
Symbol name : ?sm_eventTable#wxApp##1UwxEventTable##B (protected: static struct wxEventTable const wxApp::sm_eventTable)
Type : data
Name type : name
Hint : 14083
Name : ?sm_eventTable#wxApp##1UwxEventTable##B
From this I infer that wxmsw31u_core.lib this is an "import library" : in other words that means that this lib does not contain the code but just refers to the dll file wxmsw310u_core_vc140_x64.dll that actually contains the code.
The latter wxmsw310u_core_vc140_x64.dll file indeed mentions ?sm_eventTable#wxApp##1UwxEventTable##B as I checked:
dumpbin /EXPORTS wxmsw310u_core_vc140_x64.dll > here2.txt
gave
14084 3703 0057F008 ?sm_eventTable#wxApp##1UwxEventTable##B = ?sm_eventTable#wxApp##1UwxEventTable##B (protected: static struct wxEventTable const wxApp::sm_eventTable)
I note that the first number is equal to the hint of the previous header plus one. I suppose this is normal?
I took the time to check the DLL as above but AFAIK, the DLL is not required in the linking process (it is required when you call the .exe that is produced).
All in all, it seems everything is there and it should link, so I am at a loss to determine what's wrong here.
Edit
I partially solved the problem by compiling myself the libary instead of using the compiled binaires for Windows provided by wxWidgets: I can now compile my program and all is well.
Well, not all: the initial question remains. I had a situation where I tried to link an obj with a lib to get an exe, the obj refers to a symbol whose mangled name is present verbatim in the lib, the linker does load the obj and lib (confirmed using /VERBOSE), yet the linker refuses to consider the symbol as "resolved". Why?
I'll create a new question where I'll ask for explanations about the conditions to be resolved.
AFAIK, this long line says that my main.obj refers to a function to which a symbol ?
Yes, linker is not able to find sm_eventTable#wxApp##1UwxEventTable##B on your paths specified.
Check that you have properly setup Additional Library Path parameter and that target platform of your application is /Machine:X64
I have two kernel modules (say modA and modB). modA exports a symbol with EXPORT_SYMBOL(symA) and modB uses it. I have the header modA.h for modA:
...
extern void symA(int param);
...
and in modB.c:
#include "modA.h"
...
static int __init modB_init(void)
{
symA(10);
}
...
If i insmod modB all works fine, my modB is correctly linked in the kernel and the function symA is correctly called. However when i build modB the compiler raises a warning: symA is undefined. An LKM is an ELF relocatable so why the compiler raises this warning? How can be this removed?
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.