Makefile 从多个文件编译内核模块时出现未知符号

Makefile 从多个文件编译内核模块时出现未知符号,makefile,linux-kernel,kernel,linux-device-driver,kernel-module,Makefile,Linux Kernel,Kernel,Linux Device Driver,Kernel Module,我正在编写一个内核模块,它由几个源文件组成, 其中一个源文件具有需要由同一模块中的其他对象使用的函数 它是在名为ModemAPI.c的文件中定义的 static void LogMessage ( char *format, ...) 此c文件应(与其他文件一起)编译到一个内核模块中,其makefile如下所示: obj-m += ModemAPI.o ModemAPI-objs := ../Common/StateMachine.o ../Common/ElementsPool.o 当

我正在编写一个内核模块,它由几个源文件组成, 其中一个源文件具有需要由同一模块中的其他对象使用的函数

它是在名为ModemAPI.c的文件中定义的

static void LogMessage ( char *format, ...)
此c文件应(与其他文件一起)编译到一个内核模块中,其makefile如下所示:

obj-m += ModemAPI.o

ModemAPI-objs := ../Common/StateMachine.o ../Common/ElementsPool.o 
当我编译这个内核模块时,我在链接过程中得到一个警告,上面的函数“LogMessage”未定义,当我尝试加载模块时,我得到一个错误,说它有一个未知的符号(当然是LogMessage)

编辑:为了说明这一点,函数“LogMessage”是在ModemAPI.c文件中声明和实现的,而且它是通过EXPORT\u符号导出的

EXPORT_SYMBOL(LogMessage);
在使用该函数的文件(如StateMachine.c)中,它是通过extern声明的

extern void LogMessage ( char *format, ...);
模块编译时,问题在链接阶段

有人知道这有什么问题吗

谢谢,
Roy.

回答:
而且它是通过导出符号导出的

EXPORT\u SYMBOL()
使可加载内核模块可以访问
LogMessage()

对于eample,
vmalloc()
被导出以在内核模块中使用

但仍然必须包含可加载内核模块源代码。因此,不要与extern和EXPORT_符号混淆

解决方案

在Makefile中,按如下所示进行修改

obj-m += ModemAPI.c StateMachine.c
i、 应首先编译包含LogMessage()的e ModemAPI.c

提议对Makefile进行的更改

obj-m += Mymodule.o

Mymodule-objs := ../Common/ModemAPI.o ../Common/StateMachine.o ../Common/ElementsPool.o 
编辑:2

static in
static void LogMessage(char*格式,…)
限制在其他文件中使用LogMessage()。这个概念在Makefile中被称为。

obj-m += Module.o

Module-objs :=  ../Common/StateMachine.o ../Common/ElementsPool.o ../Common/ModemAPI.o

有时.o文件的顺序很重要

我认为问题在于没有编译ModemAPI.c

obj-m+=ModemAPI.o
ModemAPI objs:=../Common/StateMachine.o../Common/ElementsPool.o

通常
obj-m+=ModemAPI.o
告诉
make
使用ModemAPI.c(我认为这是linux make系统的默认设置),但是添加ModemAPI objs告诉
make
ModemAPI.o是使用对象
。/Common/StateMachine.o../Common/ElementsPool.o
构建的

尝试重命名对象或ModemAPI.c文件:

 obj-m += modem.o #something not named ModemAPI.o
 ModemAPI-objs := ModemAPI.o ../Common/StateMachine.o ../Common/ElementsPool.o 

其中ModemAPI.c已重命名为main.c

  • 确保编译内核时支持模块加载(例如,如果
    /proc/modules
    存在,则可以确定它确实存在)
  • 确保您是在同一个内核上编译的,您正在尝试加载模块
  • 定义
    obj-m
    +=。。。和
    [my module ko]-objs
    :=[所有xx.o对象列表]

  • 我想,你应该看一下这一节嗨,请阅读我通过编辑添加的那一节,符号是通过使用函数的文件中的extern定义的。StateMachine.c不是一个单独的模块,它是一个源文件,将(连同ModemAPI.c)编译成单个模块。首先,感谢您的帮助。其次,我尝试了您建议的makefile,但问题仍然存在。警告:“LogMessage”[Base/Driver/Mymodule.ko]未定义!
     obj-m += ModemAPI.o 
     ModemAPI-objs := main.o ../Common/StateMachine.o ../Common/ElementsPool.o