0

I am writing a kernel module that is comprised of several source files, One of these source files has a function that needs to be used by the other objects in the same module.

It is defined in my file named ModemAPI.c

static void LogMessage ( char *format, ...)

This c file should be (together with other files) compiled into one kernel module, its makefile looks like this:

obj-m += ModemAPI.o

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

When I compile this kernel module, I get a warning during linking that the above function "LogMessage" is undefined and when I try to load the module I get an error saying it has an unknown symbol in it (of course LogMessage).

EDIT: Just to make clear, the function "LogMessage" is declared and implemented in the file ModemAPI.c, moreover it is exported via EXPORT_SYMBOL

EXPORT_SYMBOL(LogMessage);

In the files that use the function (such as StateMachine.c), it is declared via extern

extern void LogMessage ( char *format, ...);

The module compiles, the problem is in the linking stage.

Does anyone have any idea what could be the problem with this?

Thanks, Roy.

geocodezip
  • 158,664
  • 13
  • 220
  • 245
Roy
  • 1
  • 2
  • I guess, you should look this section once http://en.wikipedia.org/wiki/Forward_declaration – Jeyaram Jan 02 '14 at 12:16
  • Hi, please read the section I have added via edit, the symbols are defined via extern in the file that uses the function. – Roy Jan 02 '14 at 12:31

4 Answers4

0

Answer for : moreover it is exported via EXPORT_SYMBOL

EXPORT_SYMBOL() makes LogMessage() is accessible to loadable kernel modules.

For eample, vmalloc() is exported to use in kernel modules http://lxr.free-electrons.com/source/mm/vmalloc.c#L1708

But still you have to include the vmalloc.h in loadable kernel module source.so do not confuse with extern and EXPORT_SYMBOL.

Solution

In your Makefile, modify as below

obj-m += ModemAPI.c StateMachine.c

i.e ModemAPI.c which has LogMessage() should be compiled first.

Change proposed to Makefile

obj-m += Mymodule.o

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

EDIT : 2

static in static void LogMessage ( char *format, ...) restricts the use of LogMessage() in other files. This concept is called static functions.

Community
  • 1
  • 1
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • StateMachine.c is not a seperate module, it is a source file that will compile (together with ModemAPI.c) into a single module. – Roy Jan 02 '14 at 13:21
  • First of all, thanks for the help. Second, I tried the makefile you have suggested and the problem remains the same. WARNING: "LogMessage" [Base/Driver/Mymodule.ko] undefined! – Roy Jan 02 '14 at 14:36
0

In the Makefile try

obj-m += Module.o

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

some times the order of the .o files are important

0

I believe the issue is that ModemAPI.c is not getting compiled.

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

Normally obj-m += ModemAPI.o tells make to use ModemAPI.c (I think that is the default for the linux make system), but adding the ModemAPI-objs tells make that ModemAPI.o is built using the objects ../Common/StateMachine.o ../Common/ElementsPool.o instead.

Try renaming the object or your ModemAPI.c file:

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

or

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

where ModemAPI.c has been renamed to main.c

benf
  • 915
  • 1
  • 9
  • 28
0
  1. Make sure, that your kernel is compiled with support for module loading (e.g., if /proc/modules exists, you can be sure, it is)
  2. Make sure, you are compiling against the same kernel, where you are trying to load the module
  3. define obj-m += ... and [my-module-ko]-objs := [all xx.o object list]
tpcz
  • 186
  • 1
  • 4