2017-10-06 27 views
0

私はOpenwrtでカーネルモジュールを開発する方法を学んでいます。私はこんにちは世界を試してみます。パッケージのディレクトリツリーは次のとおりです。Openwrtカーネルモジュール

khelloworld/ 

    Makefile 

    src/ 

     khelloworld.c 

     Makefile 

OpenWrtのMakefileのソース:

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

ソースのMakefile:

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関数の予期されたメッセージを表示しません。

が、それは私がinsmodが欠落していると考え

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

このメッセージが表示されます。だから、僕は"$(eval $(call KernelPackage,khelloworld))"

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

前のMakefileへのインストール次のマクロを追加しましたが、それは問題を解決しませんでした。 この問題に関するアイデアは誰にもありますが、どのように解決できますか?

+0

あなたはinitとexit文がありません。あなたはそれを試しましたか? – LethalProgrammer

+0

問題を解決しない@LethalProgrammer –

+0

modprobeを使用してモジュールをロードしましたか? – LethalProgrammer

答えて

1

ロードモジュールにinit文とexit文がありません。

__init:ロード可能なモジュール

__exitをマクロはinit関数を廃棄させると、そのメモリが解放init関数が内蔵ドライバの完了後ではなく、:モジュールがある場合にマクロ機能の漏れを引き起こしますカーネルに組み込まれ、__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. 
  • のMo:たとえば


    duleがカーネルに挿入されると、module_initマクロが呼び出され、関数hello_initが呼び出されます。

  • モジュールはrmmodで削除され、module_exitマクロが呼び出され、hello_exitが呼び出されます。 dmesgコマンドを使用すると、サンプルのカーネルモジュールの出力を見ることができます。


追加情報、Linux Load Moduleの構築の詳細については

  1. デバッグに関する別の情報Linux Kernel Load Module using GDB

1

モジュールのカーネルバージョンとカーネル機能を、モジュールをロードするカーネルと互換性を持たせる必要があります。

バージョン文字列にはSMP preemptという機能がありませんので、作業用カーネルの設定をカーネルソース/ヘッダツリーにコピーすると問題が解決するはずです。いいね:

cp /boot/config-`uname -r` /usr/src/linux-`uname -r`/.config 
関連する問題