2017-10-06 156 views
0

我正在学习如何在Openwrt中开发一个内核模块。我做一个你好世界尝试。包目录树是:Openwrt内核模块

khelloworld/ 

    Makefile 

    src/ 

     khelloworld.c 

     Makefile 

在openwrt生成文件源:

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)) 

源生成文件:

obj-m += khelloworld.o 

all: 
    $(MAKE) -C "$(LINUX_DIR)" \ 
    $(MAKE_OPTS) \ 
    modules 

与c的HelloWorld源:

#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"); 
} 

该模块用这个命令编译好:让包/ khelloworld /编译

然后我用这个命令安装它在我的OpenWrt:

opkg install kmod-khelloworld-xxxxxx.ipk 

,并没有错误完成安装。但问题dmesg不显示init函数的预期消息。

但它显示此消息

[ 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 ' 

我认为insmod丢失。所以我增加了以下安装宏Makefile文件只是"$(eval $(call KernelPackage,khelloworld))"

define Build/install 
    insmod $(PKG_BUILD_DIR)/khelloworld.ko 
endef 

之前,但没有解决不了的问题。 有没有人有关于这个问题的想法,以及我如何纠正它?

+0

你错过了init和exit语句。你尝试过吗? – LethalProgrammer

+0

@LethalProgrammer不能解决问题 –

+0

您是否使用modprobe添加了加载模块? – LethalProgrammer

回答

1

您的加载模块中没有init和exit语句。

__init:宏导致init函数将被丢弃,并且一旦初始化函数完成对内置的驱动程序,但不加载模块

其存储器释放

__exit:宏导致函数的省略当模块是内置到内核中,并像__exit一样。

建立司机不仅不需要清理功能

您可以使用modprobe,并从Linux内核删除模块。


例如:

#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); 

插入/取出样品内核模块

# insmod hello.ko 

# dmesg | tail -1 
Hello world! 

# rmmod hello.ko 

# dmesg | tail -1 
Cleaning up module. 
  • 沫dule被插入内核,module_init宏将被调用,它将调用函数hello_init。

  • 模块被删除与rmmod,module_exit宏将被调用,这将调用hello_exit。使用dmesg命令,我们可以看到示例内核模块的输出。


更多信息,

  1. 有关建设Linux Load Module更多信息。

  2. 关于调试的另一个信息Linux Kernel Load Module using GDB

1

您必须使内核版本和模块中的内核功能与您希望将模块加载到的内核兼容。

由于您的版本字符串没有功能SMP preempt,我认为将工作内核配置复制到您的内核源代码/头文件树中应该可以解决您的问题。像:

cp /boot/config-`uname -r` /usr/src/linux-`uname -r`/.config