4

Hello stackoverflowers :)

For the last several hours I've been trying to compile+load a multiple file module. The compilation emits a strange warning and the module fails to load. Here are the module, Makefile, compilation output and dmesg.

header:

// header.h

#ifndef _HEADER_H
#define _HEADER_H
void do_module_func(void);
void do_other_func(void);
#endif

'main' module file:

//mymodule.c

#include <linux/module.h>
#include <linux/kernel.h>
#include "header.h"

void do_module_func(void)
{
    printk(KERN_INFO "module_func\n");
}

static int mymodule_init(void)
{
    printk(KERN_INFO "Hello world\n");
    do_other_func();
    return 0;
}
module_init(mymodule_init);


static void mymodule_exit(void)
{
    printk(KERN_INFO "Goodbye, cruel world\n");
}
module_exit(mymodule_exit);

MODULE_LICENSE("GPL")

other c file, which calls do_module_func() that sits in the 'main' module

//other_file.c

#include "header.h"
#include <linux/kernel.h>

void do_other_func(void)
{
    printk(KERN_INFO "other_func\n");
    do_module_func();
}

Makefile

//Makefile

obj-m := mymodule.o
mymodule-objs := other_file.o

CROSS:=arm-unknown-linux-gnueabi-
KERNEL:= ~/work/linux-davinci-2.6.38/
ARCH:=arm

PWD:=$(shell pwd)

all:
    $(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules

clean:
    $(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) clean

I'm cross compiling but I believe this shouldn't be a problem. make output:

make CROSS_COMPILE....
make[1]: Entering directory .../linux-davinci-2.6.38
  CC [M] .../other_file.o
  LD [M] .../mymodule.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "do_module_func" [.../mymodule.o] undefined! <--- warning here
  CC .../mymodule.mod.o
  LD [M] .../mymodule.ko
make[1]: Leaving directory .../linux-davinci-2.6.38

insmod output:

can't insert 'mymodule.ko': unknown symbol in module, or unknown parameter

dmesg:

mymodule: Unknown symbol do_mdule_func (err 0)

Thus the module compiles with a (linkage?) warning and the module doesn't load.

Now, I see that in the make output there appears to be a linkage attempt after compiling other_file.c, but shouldn't there be a compilation of also mymodule.c before the linkage?

Thanks! :)

Bugum Burum
  • 171
  • 2
  • 8

3 Answers3

10

Turns out the problem was in the Makefile. The 'trick' is that you define in obj-m the module that will be compiled (into a .ko) and in the -objs you write all the source files.
Thus the definitions in this Makefile turn to:

obj-m := moduleko.o
moduleko-objs := other_file.o mymodule.o

and this is compiled into moduleko.ko.

Bugum Burum
  • 171
  • 2
  • 8
  • Cool, this is what I suspected. – Peter L. May 23 '13 at 16:50
  • 1
    @BagumBurum, thank you. It is important, that `moduleko-objs` should named as name module. – Denis Feb 25 '15 at 21:51
  • I ran into a similar problem, but instead of getting an error from insmod it just appeared as though the init and exit functions weren't being called, even though it was listed by lsmod. After renaming the files and updating the makefile as in your answer it worked. However, I am not really satisfied because I don't know why the original method didn't work. – Mr. Shickadance Aug 19 '16 at 14:19
0

This is because file_2 required file_1 symbol reference for building file_2 as LKM. To overcome this, build file_1(LKM) and place the Module.symvers of file_1 in file_2 location. And build the file_2 again.

-1
all:
    $(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
instead try like this
     $(MAKE) -C  $(KERNEL) ARCH=$(ARCH)  CROSS_COMPILE=$(CROSS) M=$(PWD) /
          this will run each file and links with object.hope this would solve your problem
samayo
  • 16,163
  • 12
  • 91
  • 106
Sudharasan D
  • 119
  • 5