内核 Makefile 没有为我的模块创建任何 .ko 文件
Kernel Makefile does not create any .ko file for my module
我想制作非常简单的模块。所以,我刚刚制作了一个 hello_module.c
文件和一个 Makefile
.
Makefile
:
obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean
hello_module.c
:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kthread.h> // for thread
#include <linux/slab.h> // for kmalloc
#include <linux/delay.h>
int test_thread(void * _arg) {
int * arg = (int * ) _arg;
printk("argument : %d\n", * arg);
kfree(arg);
return 0;
}
void thread_create(void) {
int i;
/* thread create */
for (i = 0; i < 10; i++) {
int * arg = (int * ) kmalloc(sizeof(int), GFP_KERNEL);
* arg = i;
kthread_run( & test_thread, (void * ) arg, "test_thread");
}
}
int __init hello_module_init(void) {
thread_create();
printk(KERN_EMERG "Hello Module\n");
return 0;
}
但是,它没有生成任何 .ko
文件。另外,没有错误。
结果如下:
rashta@rashta-VirtualBox:~/Desktop/ehh$ sudo make
[sudo] password for rashta:
make -C /lib/modules/5.4.71yujin/build SUBDIRS=/home/rashta/Desktop/ehh modules
make[1]: Entering directory '/usr/src/linux-5.4.71'
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
DESCEND objtool
CHK kernel/kheaders_data.tar.xz
Building modules, stage 2.
MODPOST 5483 modules
make[1]: Leaving directory '/usr/src/linux-5.4.71'
我做错了什么?
你的Makefile
错了。为了构建内核模块,您需要传递 M=
,而不是 SUBDIRS=
。这应该有效:
obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
此外,您的模块缺少一些无法成功编译的部分,即定义要使用哪个函数的 module_init()
宏。将以下内容添加到您的代码中:
void __exit hello_module_exit(void) {
// Not required, but needed to be able to unload the module.
return;
}
module_init(hello_module_init);
module_exit(hello_module_exit);
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("Test module");
MODULE_AUTHOR("You");
MODULE_LICENSE("GPL");
长期以来,kbuild 以与 M=
相同的方式处理 SUBDIRS=
参数。在 Linux 内核 5.3 之后不再如此:对 SUBDIRS=
的支持已被 删除。
因此,应该使用 M=$(PWD)
.
而不是 SUBDIRS=$(PWD)
可以在 Makefile 中找到 5.3 版本(但不是之后!)的以下警告:
ifdef SUBDIRS
$(warning ================= WARNING ================)
$(warning 'SUBDIRS' will be removed after Linux 5.3)
$(warning )
$(warning If you are building an individual subdirectory)
$(warning in the kernel tree, you can do like this:)
$(warning $$ make path/to/dir/you/want/to/build/)
$(warning (Do not forget the trailing slash))
$(warning )
$(warning If you are building an external module,)
$(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
$(warning ==========================================)
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
我想制作非常简单的模块。所以,我刚刚制作了一个 hello_module.c
文件和一个 Makefile
.
Makefile
:
obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) clean
hello_module.c
:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kthread.h> // for thread
#include <linux/slab.h> // for kmalloc
#include <linux/delay.h>
int test_thread(void * _arg) {
int * arg = (int * ) _arg;
printk("argument : %d\n", * arg);
kfree(arg);
return 0;
}
void thread_create(void) {
int i;
/* thread create */
for (i = 0; i < 10; i++) {
int * arg = (int * ) kmalloc(sizeof(int), GFP_KERNEL);
* arg = i;
kthread_run( & test_thread, (void * ) arg, "test_thread");
}
}
int __init hello_module_init(void) {
thread_create();
printk(KERN_EMERG "Hello Module\n");
return 0;
}
但是,它没有生成任何 .ko
文件。另外,没有错误。
结果如下:
rashta@rashta-VirtualBox:~/Desktop/ehh$ sudo make
[sudo] password for rashta:
make -C /lib/modules/5.4.71yujin/build SUBDIRS=/home/rashta/Desktop/ehh modules
make[1]: Entering directory '/usr/src/linux-5.4.71'
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
DESCEND objtool
CHK kernel/kheaders_data.tar.xz
Building modules, stage 2.
MODPOST 5483 modules
make[1]: Leaving directory '/usr/src/linux-5.4.71'
我做错了什么?
你的Makefile
错了。为了构建内核模块,您需要传递 M=
,而不是 SUBDIRS=
。这应该有效:
obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
此外,您的模块缺少一些无法成功编译的部分,即定义要使用哪个函数的 module_init()
宏。将以下内容添加到您的代码中:
void __exit hello_module_exit(void) {
// Not required, but needed to be able to unload the module.
return;
}
module_init(hello_module_init);
module_exit(hello_module_exit);
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("Test module");
MODULE_AUTHOR("You");
MODULE_LICENSE("GPL");
长期以来,kbuild 以与 M=
相同的方式处理 SUBDIRS=
参数。在 Linux 内核 5.3 之后不再如此:对 SUBDIRS=
的支持已被 删除。
因此,应该使用 M=$(PWD)
.
SUBDIRS=$(PWD)
可以在 Makefile 中找到 5.3 版本(但不是之后!)的以下警告:
ifdef SUBDIRS
$(warning ================= WARNING ================)
$(warning 'SUBDIRS' will be removed after Linux 5.3)
$(warning )
$(warning If you are building an individual subdirectory)
$(warning in the kernel tree, you can do like this:)
$(warning $$ make path/to/dir/you/want/to/build/)
$(warning (Do not forget the trailing slash))
$(warning )
$(warning If you are building an external module,)
$(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
$(warning ==========================================)
KBUILD_EXTMOD ?= $(SUBDIRS)
endif