0
votes

Conclusion

When compiling only one file for a driver module, everything works. If I add a .c/.h module to the previous file, it compiles again. But I'm not able to load the module into the kernel.

Details

I'm working on a RPi3B+ over ssh from my Ubunto LTS 18.04 Host system. Currently I'm not using any crosstools, but building directly on the RPi.

I'm developing a kernel moudle. Now that my module has increased in size, I would like to separate it into different .h/.c modules.

To start, I implemented an example from the book "Embedded Linux, lernen mit dem Raspberry Pi". However it's in german.

Everything worked fine till I add the additional object files to the Makefile. Before that, I could load and unload the module and could see every output form "printk()". Also I can reproduce it again!

But if I compile it with the additional files, everything works fine, no erros no warnings. But if I try to load the new module with "insmod". No response from the kernel on "dmesg". No new device under /dev/ But "lsmod" knows it!

Is there something special if I want to add several .c/.h files to my driver module?

Makefile

ifneq ($(KERNELRELEASE),)
obj-m := kernel_nfc_module.o
kernel_nfc_module-objs := kernel_gpio.o

else
KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

default:
        $(MAKE)  -Wall -C $(KDIR) M=$(PWD) modules 
endif

clean:
        rm -rf *.ko *.o .*.cmd .tmp_versions Module.symvers
        rm -rf modules.order *.mod.c

kernel_gpio.h

#ifndef KERNEL_GPIO_H
#define KERNEL_GPIO_H
MODULE_LICENSE("GPL");

void sayHello(void);

#endif // KERNEL_GPIO_H

kernel_gpio.c

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/uaccess.h>

#include <linux/string.h>
#include "kernel_gpio.h"
#include "kernel_utils.h"

void sayHello(void)
{
        printk("Hello Module");
}

MODULE_LICENSE("GPL");

I'm totally confused, because o receive no errors from the compiller or insmod. I would like to know how to compile kernel module with additional .c/.h files.

Thanks for your advise.

1
Your makefile is targeted to compile a single source file - kernel_gpio.c And that source file doesn't contain module_init function which is run on the module's loading. What are other source files you are talking about?Tsyvarev
There is only one, kernel_nfc_module.c, which uses sayHello() from kernel_gpoi.h /.c. However module_init(), and the other functions needed are implemented in kernel_nfc_module.c and are working properly if only this file is compiled. I can watch on "dmesg" driver open/close and every write/read access.Matthias Waelti
So you need to add your source - kernel_nfc_module.o - to the list kernel_nfc_module-objs, which currently contains only single element. Note, that kernel module cannot at the same both consist from the several source files and has a name of one of them. So you need to rename your module name (from kernel_nfc_module) or rename your source file (kernel_nfc_module.c).Tsyvarev
Perfectly, it works for me. Thanks a lot!!Matthias Waelti

1 Answers

0
votes

Thanks to the helpful comment from Tsyvarev, I was able to solve my problem.

Solution

I had the following files:

  • kernel_nfc_module.c
  • kernel_gpio.c
  • kernel_gpio.h

Makefile

I had to add a new name for the combined object file of my two sources!

ifneq ($(KERNELRELEASE),)
obj-m := nfc_module.o
nfc_module-objs := kernel_nfc_module.o kernel_gpio.o

else
KDIR := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)

default:
        $(MAKE)  -Wall -C $(KDIR) M=$(PWD) modules 
endif

clean:
        rm -rf *.ko *.o .*.cmd .tmp_versions Module.symvers
        rm -rf modules.order *.mod.c