2016-06-29 88 views
1

首先我想說我一直在尋找類似的問題,解決方案是什麼。而且我發現,它是:從多個文件編譯內核模塊時沒有編譯主文件

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); 

的Makefile:

__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__) 

這是構建過程:

[email protected]:~/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' 
[email protected]:~/CNC-Controller$ 

當我刪除行

CNC_controller-objs := axis_controller/axis_controller.o 

建設過程:

[email protected]:~/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 "\001" /* 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 
[email protected]:~/CNC-Controller$ 

這就是爲什麼我想是不是因爲編譯它會記錄的printk的錯誤:

include/linux/kern_levels.h:4:18: error: expected declaration specifiers or ‘...’ before string constant 
    #define KERN_SOH "\001" /* ASCII Start Of Header * 

任何線索我做錯了什麼?因爲我做我見過別人正在做的事......

回答

4

你有兩個問題:

  • 你不能printk的全球範圍內使用。這必須轉移到一個功能。
  • 嘗試構建多個文件模塊時,無法使用與模塊名稱相同的C文件。也就是說,無論是重命名CNC_controller.c或.ko 例如對於重CNC_controller.cCNC_controller_main.c和使用:

    CNC_controller-的OBJ:= CNC_controller_main.c axis_controller/axis_controller.o

1

根據錯誤消息,你可以調用頂層的函數。這表明有一個主要或另一個功能以外的通話。

更準確地說printk(KERN_INFO "CNC_controller.c\n");

在旁註中#define KERN_SOH "\001"只能作爲擋塊使用,因爲'\0'是終止字符。我留給你說,如果這是你的意圖。

+0

沒有我已經添加printk cuz它只是在堆棧外調用時產生錯誤,所以我可以證明CNC_controller.c是第二次編譯的,但首先要注意(當存在依賴關係時,第一次它被鏈接...) –