问题
I'm trying to link a kernel module to a non-LKM source file. The problem is, I'm running into some issues. The names of the two files are chardev.c (the LKM) and foo.c.
My Makefile:
obj-m += chardev.o
obj-y += foo.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
$(CC) test.c -o test
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
rm test
Inside of chardev.c I've the following line of code: extern int foo;
, and inside foo I've the following line of code: int foo = 123;
. (Both lines are at file-scope.)
When running make I'm getting the following output:
make -C /lib/modules/4.4.0-31-generic/build/ M=/home/kylemart/Desktop/Device-Driver modules
make[1]: Entering directory `/usr/src/linux-headers-4.4.0-31-generic'
CC [M] /home/kylemart/Desktop/Device-Driver/chardev.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "foo" [/home/kylemart/Desktop/Device-Driver/chardev.ko] undefined!
CC /home/kylemart/Desktop/Device-Driver/chardev.mod.o
LD [M] /home/kylemart/Desktop/Device-Driver/chardev.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.4.0-31-generic'
cc test.c -o test
Seems things aren't linking properly. What am I doing wrong?
EDIT:
This seems to work, but there's a problem:
obj-m += chardev.o
chardev-objs += foo.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
$(CC) test.c -o test
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
rm test
Although it compiles without warnings, after installing the compiled module (i.e. sudo insmod chardev.ko
) there isn't a new device present in /dev
. Previously, without trying to link source files, installing kernel modules as previously stated created a device file. That said, the device is present when running lsmod
.
回答1:
Your all
target builds only the module, but not the kernel so that the foo
symbol does not exist there.
When compiling a source (here: foo.c
) into the kernel, you have to integrate the makefile into the kernel source. E.g. you have to add
obj-y += my-driver/
to the makefile in the previous directory and build the whole kernel. You should probably remove your all:
and clean:
targets from the makefile to avoid conflicts with kernel builtin rules.
foo.c
must contain
EXPORT_SYMBOL(foo);
or
EXPORT_SYMBOL_GPL(foo);
The second makefile...
will generate only the chardev.ko
module which is built from only foo.c
; chardev.c
will not be used for it. When you really want this, you have to change file names; e.g.
obj-m += chardev.o
chardev-objs = chardev-core.o foo.o
来源:https://stackoverflow.com/questions/49700578/linux-kernel-module-sharing-variables-between-source-files