简体   繁体   中英

Openwrt kernel module

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?

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,

  1. For more information about building the Linux Load Module .

  2. Another information about debugging Linux Kernel Load Module using GDB .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM