Reputation: 1218
I'm learning how to develop a kernel module in Openwrt. I make a hello world try. The package directory tree is:
khelloworld/
Makefile
src/
khelloworld.c
Makefile
The Openwrt Makefile source:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=khelloworld
PKG_RELEASE:=1
PKG_VERSION:=1.0
include $(INCLUDE_DIR)/package.mk
define KernelPackage/khelloworld
SUBMENU:=HELLO WORLD MODULES
TITLE:=khelloworld
MAINTAINER:=Nobody
MENU:=1
FILES:=$(PKG_BUILD_DIR)/$(PKG_NAME).$(LINUX_KMOD_SUFFIX)
endef
EXTRA_KCONFIG:= \
CONFIG_HELLO_MOD=m
EXTRA_CFLAGS:= \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
#MAKE_OPTS:= \
# EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
# $(EXTRA_KCONFIG)
define Build/Prepare
# Copy sources
mkdir -p $(PKG_BUILD_DIR)
cp -R ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
SUBDIRS="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
$(EXTRA_KCONFIG) \
modules
endef
$(eval $(call KernelPackage,khelloworld))
The source Makefile:
obj-m += khelloworld.o
all:
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
The C helloworld source:
#include <linux/module.h>
#include <linux/kernel.h>
int init_module( void ) {
printk( KERN_INFO "Hello World KERNEL!!!\n" );
return 0;
}
void cleanup_module( void ) {
printk( KERN_INFO "Goodbye World KERNEL!!!\n" );
}
This module compiles well with this command: make package/khelloworld/compile
Then I installed it in my openwrt using this command:
opkg install kmod-khelloworld-xxxxxx.ipk
and the install is done without errors. but the problem dmesg
doesn't display the expected message of the init function.
but it displays this message
[ 9493.863000] khelloworld: version magic '3.4.11-rt19 mod_unload modversions MIPS32_R1 32BIT ' should be '3.4.11-rt19 SMP preempt mod_unload MIPS32_R1 32BIT '
I thought that insmod
is missing. So I added the following install macro to the Makefile just before "$(eval $(call KernelPackage,khelloworld))"
define Build/install
insmod $(PKG_BUILD_DIR)/khelloworld.ko
endef
but that didn't solve the problem. Has anyone an idea about this problem and how I can correct it?
Upvotes: 2
Views: 6168
Reputation: 681
You have to make kernel version AND kernel features in your module compatible with kernel you want your module load into.
As your version string doesn't have features SMP preempt
, I think copying config of work kernel into your kernel-source/header tree should solve your problem. Like:
cp /boot/config-`uname -r` /usr/src/linux-`uname -r`/.config
Upvotes: 2
Reputation: 4920
You are not having the init and exit statement in your load module.
__init: macro causes the init function to be discarded and its memory freed once the init function finishes for built-in drivers, but not loadable modules
__exit: macro causes the omission of the function when the module is built into the kernel, and like __exit.
build in drivers only don't need the clean-up functions
You can use modprobe
to and remove the module from the Linux Kernel.
For example:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h> /* Needed for the macros */
int __init hello_init( void ) {
printk( KERN_INFO "Hello World KERNEL!!!\n" );
return 0;
}
void __exit hello_exit( void ) {
printk( KERN_INFO "Goodbye World KERNEL!!!\n" );
}}
module_init(hello_2_init);
module_exit(hello_2_exit);
Insert/Remove the sample kernel module
# insmod hello.ko
# dmesg | tail -1
Hello world!
# rmmod hello.ko
# dmesg | tail -1
Cleaning up module.
Module is inserted into the kernel, the module_init macro will be invoked, which will call the function hello_init.
Module is removed with rmmod, module_exit macro will be invoked, which will call the hello_exit. Using dmesg command, we can see the output from the sample Kernel module.
Additional information,
For more information about building the Linux Load Module.
Another information about debugging Linux Kernel Load Module using GDB.
Upvotes: 3