我正在编写一个由几个源文件组成的内核模块, 其中一个源文件具有需要由同一模块中的其他对象使用的函数。
它在我的名为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_SYMBOL导出
EXPORT_SYMBOL(LogMessage);
在使用该函数的文件(例如StateMachine.c)中,它是通过extern声明的
extern void LogMessage ( char *format, ...);
模块编译,问题处于链接阶段。
有没有人知道这可能是什么问题?
谢谢, 罗伊。
答案 0 :(得分:0)
回答:moreover it is exported via EXPORT_SYMBOL
EXPORT_SYMBOL()
使LogMessage()
可供可加载内核模块访问。
例如,导出vmalloc()
以在内核模块http://lxr.free-electrons.com/source/mm/vmalloc.c#L1708
但是你仍然需要在可加载内核模块源中包含vmalloc.h。所以不要与extern和EXPORT_SYMBOL混淆。
<强>解决方案强>
在Makefile中,修改如下
obj-m += ModemAPI.c StateMachine.c
即应首先编译具有LogMessage()的ModemAPI.c。
建议更改为Makefile
obj-m += Mymodule.o
Mymodule-objs := ../Common/ModemAPI.o ../Common/StateMachine.o ../Common/ElementsPool.o
编辑:2
static void LogMessage ( char *format, ...)
中的static限制在其他文件中使用LogMessage()。这个概念称为static functions。
答案 1 :(得分:0)
在Makefile中尝试
obj-m += Module.o
Module-objs := ../Common/StateMachine.o ../Common/ElementsPool.o ../Common/ModemAPI.o
有时候.o文件的顺序很重要
答案 2 :(得分:0)
我认为问题是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
或
obj-m += ModemAPI.o
ModemAPI-objs := main.o ../Common/StateMachine.o ../Common/ElementsPool.o
其中ModemAPI.c已重命名为main.c
答案 3 :(得分:0)
/proc/modules
存在,您可以确定,它是)obj-m
+ = ...和[my-module-ko]-objs
:= [所有xx.o对象列表]