从多个文件编译内核模块时主文件未编译
Main file not compiling when compiling kernel module from multiple files
首先我想说一下,我一直在寻找类似的问题,解决方案是什么。我发现它是:
obj-m := module.o
module-objs := extra.o
但它对我不起作用...
这是整个项目的来源:
axis_controller.h:
#ifndef _AXIS_CONTROLLER_H
#define _AXIS_CONTROLLER_H
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
struct axis_controller {
struct hrtimer timer;
int state;
};
static inline struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller);
static inline void axis_controller_reset_state(struct axis_controller* axis_controller);
inline void axis_controller_init(struct axis_controller* axis_controller, enum hrtimer_restart (*function)(struct hrtimer *));
inline int axis_controller_clean(struct axis_controller* axis_controller);
inline void axis_controller_change_state(struct axis_controller* axis_controller, unsigned long sec, unsigned long nano_sec);
inline void axis_controller_controll(struct axis_controller* axis_controller);
#endif
axis_controller.c:
#include "axis_controller.h"
MODULE_LICENSE("GPL v2");
struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller) {
return &(axis_controller->timer);
}
void axis_controller_reset_state(struct axis_controller* axis_controller) {
axis_controller->state = 0;
}
void axis_controller_init(struct axis_controller* axis_controller, enum hrtimer_restart (*function)(struct hrtimer *)) {
hrtimer_init(axis_controller_get_timer(axis_controller), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
axis_controller->timer.function = function;
axis_controller_reset_state(axis_controller);
}
int axis_controller_clean(struct axis_controller* axis_controller) {
return hrtimer_try_to_cancel(axis_controller_get_timer(axis_controller));
}
void axis_controller_change_state(struct axis_controller* axis_controller, unsigned long sec, unsigned long nano_sec) {
axis_controller->state = !axis_controller->state;
hrtimer_start(axis_controller_get_timer(axis_controller), ktime_set(sec, nano_sec), HRTIMER_MODE_REL);
}
void axis_controller_controll(struct axis_controller* axis_controller) {
axis_controller_reset_state(axis_controller);
axis_controller->timer.function(axis_controller_get_timer(axis_controller));
}
//printk(KERN_INFO "axis_controller.c\n");
CNC_controller.c:
#include <linux/kernel.h>
#include <linux/module.h>
#include "axis_controller/axis_controller.h"
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ivo Stratev (NoHomey)");
MODULE_DESCRIPTION("CNC Controller");
printk(KERN_INFO "CNC_controller.c\n");
static int return_value;
static struct axis_controller test;
static enum hrtimer_restart my_callback(struct hrtimer *timer) {
printk(KERN_INFO "my_hrtimer_callback called\n");
return HRTIMER_NORESTART;
}
static int __init on_load(void) {
printk("on_load\n");
axis_controller_init(&test, my_callback);
axis_controller_controll(&test);
return 0;
}
static void on_unload(void) {
printk("on_unload\n");
axis_controller_clean(&test);
return;
}
module_init(on_load);
module_exit(on_unload);
生成文件:
__name__ = CNC_controller
__major__ = 243
__ioctl_header__ = /usr/include/$(__name__)_ioctl.h
make_module_action = make -C /lib/modules/$(shell uname -r)/build M=$(PWD)
obj-m := $(__name__).o
CNC_controller-objs := axis_controller/axis_controller.o
all: clean
$(make_module_action) modules
clean:
$(make_module_action) clean
load:
insmod $(__name__).ko
unload:
rmmod -f $(__name__)
device:
mknod /dev/$(__name__) c $(__major__) 0
chmod 777 /dev/$(__name__)
remove:
rm -f /dev/$(__name__)
header:
rm -f $(__ioctl_header__)
cp $(__name__).h $(__ioctl_header__)
chmod 555 $(__ioctl_header__)
这是构建过程:
ivo@ivo-Inspiron-5558:~/CNC-Controller$ make
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller clean
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CLEAN /home/ivo/CNC-Controller/.tmp_versions
CLEAN /home/ivo/CNC-Controller/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CC [M] /home/ivo/CNC-Controller/axis_controller/axis_controller.o
LD [M] /home/ivo/CNC-Controller/CNC_controller.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/ivo/CNC-Controller/CNC_controller.mod.o
LD [M] /home/ivo/CNC-Controller/CNC_controller.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
ivo@ivo-Inspiron-5558:~/CNC-Controller$
当我删除线时
CNC_controller-objs := axis_controller/axis_controller.o
构建过程为:
ivo@ivo-Inspiron-5558:~/CNC-Controller$ make
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller clean
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CLEAN /home/ivo/CNC-Controller/.tmp_versions
CLEAN /home/ivo/CNC-Controller/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CC [M] /home/ivo/CNC-Controller/CNC_controller.o
In file included from include/linux/printk.h:6:0,
from include/linux/kernel.h:13,
from /home/ivo/CNC-Controller/CNC_controller.c:2:
include/linux/kern_levels.h:4:18: error: expected declaration specifiers or ‘...’ before string constant
#define KERN_SOH "[=17=]1" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:13:19: note: in expansion of macro ‘KERN_SOH’
#define KERN_INFO KERN_SOH "6" /* informational */
^
/home/ivo/CNC-Controller/CNC_controller.c:10:8: note: in expansion of macro ‘KERN_INFO’
printk(KERN_INFO "CNC_controller.c\n");
^
In file included from /home/ivo/CNC-Controller/CNC_controller.c:4:0:
/home/ivo/CNC-Controller/axis_controller/axis_controller.h:14:31: warning: ‘axis_controller_get_timer’ declared ‘static’ but never defined [-Wunused-function]
static inline struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller);
^
/home/ivo/CNC-Controller/axis_controller/axis_controller.h:16:20: warning: ‘axis_controller_reset_state’ declared ‘static’ but never defined [-Wunused-function]
static inline void axis_controller_reset_state(struct axis_controller* axis_controller);
^
scripts/Makefile.build:264: recipe for target '/home/ivo/CNC-Controller/CNC_controller.o' failed
make[2]: *** [/home/ivo/CNC-Controller/CNC_controller.o] Error 1
Makefile:1403: recipe for target '_module_/home/ivo/CNC-Controller' failed
make[1]: *** [_module_/home/ivo/CNC-Controller] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
Makefile:10: recipe for target 'all' failed
make: *** [all] Error 2
ivo@ivo-Inspiron-5558:~/CNC-Controller$
这就是我认为它没有编译的原因,因为它记录了 printk 错误:
include/linux/kern_levels.h:4:18: error: expected declaration specifiers or ‘...’ before string constant
#define KERN_SOH "[=18=]1" /* ASCII Start Of Header *
知道我哪里做错了吗?因为我做了我看到别人正在做的事情......
根据错误信息,您在顶层调用了一个函数。这表明在 main 或另一个函数之外有一个调用。
更准确地说 printk(KERN_INFO "CNC_controller.c\n");
。
旁注 #define KERN_SOH "[=11=]1"
只能作为停止符,因为 '[=12=]'
是终止符。我留给你说这是否是你想要的。
您有两个问题:
- 您不能在全局范围内使用 printk。这必须移到一个函数中。
尝试构建多文件模块时,您不能拥有与模块同名的 C 文件。也就是说,重命名 CNC_controller.c 或 .ko
例如,重命名 CNC_controller.c
CNC_controller_main.c
并使用:
CNC_controller-objs := CNC_controller_main.c axis_controller/axis_controller.o
首先我想说一下,我一直在寻找类似的问题,解决方案是什么。我发现它是:
obj-m := module.o
module-objs := extra.o
但它对我不起作用...
这是整个项目的来源:
axis_controller.h:
#ifndef _AXIS_CONTROLLER_H
#define _AXIS_CONTROLLER_H
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
struct axis_controller {
struct hrtimer timer;
int state;
};
static inline struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller);
static inline void axis_controller_reset_state(struct axis_controller* axis_controller);
inline void axis_controller_init(struct axis_controller* axis_controller, enum hrtimer_restart (*function)(struct hrtimer *));
inline int axis_controller_clean(struct axis_controller* axis_controller);
inline void axis_controller_change_state(struct axis_controller* axis_controller, unsigned long sec, unsigned long nano_sec);
inline void axis_controller_controll(struct axis_controller* axis_controller);
#endif
axis_controller.c:
#include "axis_controller.h"
MODULE_LICENSE("GPL v2");
struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller) {
return &(axis_controller->timer);
}
void axis_controller_reset_state(struct axis_controller* axis_controller) {
axis_controller->state = 0;
}
void axis_controller_init(struct axis_controller* axis_controller, enum hrtimer_restart (*function)(struct hrtimer *)) {
hrtimer_init(axis_controller_get_timer(axis_controller), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
axis_controller->timer.function = function;
axis_controller_reset_state(axis_controller);
}
int axis_controller_clean(struct axis_controller* axis_controller) {
return hrtimer_try_to_cancel(axis_controller_get_timer(axis_controller));
}
void axis_controller_change_state(struct axis_controller* axis_controller, unsigned long sec, unsigned long nano_sec) {
axis_controller->state = !axis_controller->state;
hrtimer_start(axis_controller_get_timer(axis_controller), ktime_set(sec, nano_sec), HRTIMER_MODE_REL);
}
void axis_controller_controll(struct axis_controller* axis_controller) {
axis_controller_reset_state(axis_controller);
axis_controller->timer.function(axis_controller_get_timer(axis_controller));
}
//printk(KERN_INFO "axis_controller.c\n");
CNC_controller.c:
#include <linux/kernel.h>
#include <linux/module.h>
#include "axis_controller/axis_controller.h"
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ivo Stratev (NoHomey)");
MODULE_DESCRIPTION("CNC Controller");
printk(KERN_INFO "CNC_controller.c\n");
static int return_value;
static struct axis_controller test;
static enum hrtimer_restart my_callback(struct hrtimer *timer) {
printk(KERN_INFO "my_hrtimer_callback called\n");
return HRTIMER_NORESTART;
}
static int __init on_load(void) {
printk("on_load\n");
axis_controller_init(&test, my_callback);
axis_controller_controll(&test);
return 0;
}
static void on_unload(void) {
printk("on_unload\n");
axis_controller_clean(&test);
return;
}
module_init(on_load);
module_exit(on_unload);
生成文件:
__name__ = CNC_controller
__major__ = 243
__ioctl_header__ = /usr/include/$(__name__)_ioctl.h
make_module_action = make -C /lib/modules/$(shell uname -r)/build M=$(PWD)
obj-m := $(__name__).o
CNC_controller-objs := axis_controller/axis_controller.o
all: clean
$(make_module_action) modules
clean:
$(make_module_action) clean
load:
insmod $(__name__).ko
unload:
rmmod -f $(__name__)
device:
mknod /dev/$(__name__) c $(__major__) 0
chmod 777 /dev/$(__name__)
remove:
rm -f /dev/$(__name__)
header:
rm -f $(__ioctl_header__)
cp $(__name__).h $(__ioctl_header__)
chmod 555 $(__ioctl_header__)
这是构建过程:
ivo@ivo-Inspiron-5558:~/CNC-Controller$ make
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller clean
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CLEAN /home/ivo/CNC-Controller/.tmp_versions
CLEAN /home/ivo/CNC-Controller/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CC [M] /home/ivo/CNC-Controller/axis_controller/axis_controller.o
LD [M] /home/ivo/CNC-Controller/CNC_controller.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/ivo/CNC-Controller/CNC_controller.mod.o
LD [M] /home/ivo/CNC-Controller/CNC_controller.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
ivo@ivo-Inspiron-5558:~/CNC-Controller$
当我删除线时
CNC_controller-objs := axis_controller/axis_controller.o
构建过程为:
ivo@ivo-Inspiron-5558:~/CNC-Controller$ make
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller clean
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CLEAN /home/ivo/CNC-Controller/.tmp_versions
CLEAN /home/ivo/CNC-Controller/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
make -C /lib/modules/4.4.0-28-generic/build M=/home/ivo/CNC-Controller modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-28-generic'
CC [M] /home/ivo/CNC-Controller/CNC_controller.o
In file included from include/linux/printk.h:6:0,
from include/linux/kernel.h:13,
from /home/ivo/CNC-Controller/CNC_controller.c:2:
include/linux/kern_levels.h:4:18: error: expected declaration specifiers or ‘...’ before string constant
#define KERN_SOH "[=17=]1" /* ASCII Start Of Header */
^
include/linux/kern_levels.h:13:19: note: in expansion of macro ‘KERN_SOH’
#define KERN_INFO KERN_SOH "6" /* informational */
^
/home/ivo/CNC-Controller/CNC_controller.c:10:8: note: in expansion of macro ‘KERN_INFO’
printk(KERN_INFO "CNC_controller.c\n");
^
In file included from /home/ivo/CNC-Controller/CNC_controller.c:4:0:
/home/ivo/CNC-Controller/axis_controller/axis_controller.h:14:31: warning: ‘axis_controller_get_timer’ declared ‘static’ but never defined [-Wunused-function]
static inline struct hrtimer* axis_controller_get_timer(struct axis_controller* axis_controller);
^
/home/ivo/CNC-Controller/axis_controller/axis_controller.h:16:20: warning: ‘axis_controller_reset_state’ declared ‘static’ but never defined [-Wunused-function]
static inline void axis_controller_reset_state(struct axis_controller* axis_controller);
^
scripts/Makefile.build:264: recipe for target '/home/ivo/CNC-Controller/CNC_controller.o' failed
make[2]: *** [/home/ivo/CNC-Controller/CNC_controller.o] Error 1
Makefile:1403: recipe for target '_module_/home/ivo/CNC-Controller' failed
make[1]: *** [_module_/home/ivo/CNC-Controller] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-28-generic'
Makefile:10: recipe for target 'all' failed
make: *** [all] Error 2
ivo@ivo-Inspiron-5558:~/CNC-Controller$
这就是我认为它没有编译的原因,因为它记录了 printk 错误:
include/linux/kern_levels.h:4:18: error: expected declaration specifiers or ‘...’ before string constant
#define KERN_SOH "[=18=]1" /* ASCII Start Of Header *
知道我哪里做错了吗?因为我做了我看到别人正在做的事情......
根据错误信息,您在顶层调用了一个函数。这表明在 main 或另一个函数之外有一个调用。
更准确地说 printk(KERN_INFO "CNC_controller.c\n");
。
旁注 #define KERN_SOH "[=11=]1"
只能作为停止符,因为 '[=12=]'
是终止符。我留给你说这是否是你想要的。
您有两个问题:
- 您不能在全局范围内使用 printk。这必须移到一个函数中。
尝试构建多文件模块时,您不能拥有与模块同名的 C 文件。也就是说,重命名 CNC_controller.c 或 .ko 例如,重命名
CNC_controller.c
CNC_controller_main.c
并使用:CNC_controller-objs := CNC_controller_main.c axis_controller/axis_controller.o