Linux 内核模块 - 在源文件之间共享变量
Linux Kernel Module - Sharing variables between source files
我正在尝试 link 一个内核模块到一个非 LKM 源文件。问题是,我 运行 遇到了一些问题。这两个文件的名称是 chardev.c(LKM)和 foo.c.
我的生成文件:
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
在 chardev.c 内部我有以下代码行:extern int foo;
,在 foo 内部我有以下代码行:int foo = 123;
。 (这两行都在文件范围内。)
当 运行 make 我得到以下输出:
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
似乎事情 link 不正常。我做错了什么?
编辑:
这似乎可行,但有一个问题:
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
虽然编译时没有警告,但在安装编译模块(即 sudo insmod chardev.ko
)后,/dev
中没有新设备。以前,在不尝试 link 源文件的情况下,如前所述安装内核模块会创建一个设备文件。也就是说,设备在 运行 lsmod
.
时存在
您的 all
目标仅构建模块,而不构建内核,因此 foo
符号在那里不存在。
将源代码(此处:foo.c
)编译到内核中时,必须将生成文件集成到内核源代码中。例如。你必须添加
obj-y += my-driver/
添加到上一个目录中的makefile 并构建整个内核。您可能应该从 makefile 中删除 all:
和 clean:
目标,以避免与内核内置规则发生冲突。
foo.c
必须包含
EXPORT_SYMBOL(foo);
或
EXPORT_SYMBOL_GPL(foo);
第二个 makefile...
将仅生成仅由 foo.c
构建的 chardev.ko
模块; chardev.c
不会用于它。当你真的想要这个时,你必须更改文件名;例如
obj-m += chardev.o
chardev-objs = chardev-core.o foo.o
我正在尝试 link 一个内核模块到一个非 LKM 源文件。问题是,我 运行 遇到了一些问题。这两个文件的名称是 chardev.c(LKM)和 foo.c.
我的生成文件:
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
在 chardev.c 内部我有以下代码行:extern int foo;
,在 foo 内部我有以下代码行:int foo = 123;
。 (这两行都在文件范围内。)
当 运行 make 我得到以下输出:
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
似乎事情 link 不正常。我做错了什么?
编辑:
这似乎可行,但有一个问题:
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
虽然编译时没有警告,但在安装编译模块(即 sudo insmod chardev.ko
)后,/dev
中没有新设备。以前,在不尝试 link 源文件的情况下,如前所述安装内核模块会创建一个设备文件。也就是说,设备在 运行 lsmod
.
您的 all
目标仅构建模块,而不构建内核,因此 foo
符号在那里不存在。
将源代码(此处:foo.c
)编译到内核中时,必须将生成文件集成到内核源代码中。例如。你必须添加
obj-y += my-driver/
添加到上一个目录中的makefile 并构建整个内核。您可能应该从 makefile 中删除 all:
和 clean:
目标,以避免与内核内置规则发生冲突。
foo.c
必须包含
EXPORT_SYMBOL(foo);
或
EXPORT_SYMBOL_GPL(foo);
第二个 makefile...
将仅生成仅由 foo.c
构建的 chardev.ko
模块; chardev.c
不会用于它。当你真的想要这个时,你必须更改文件名;例如
obj-m += chardev.o
chardev-objs = chardev-core.o foo.o