Makefile 从多个文件编译内核模块时出现未知符号
我正在编写一个内核模块,它由几个源文件组成, 其中一个源文件具有需要由同一模块中的其他对象使用的函数 它是在名为ModemAPI.c的文件中定义的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 当
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 instatic 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