Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> Linuxドライバ開発モジュールおよびhelloカーネルモジュールの例のMakefileを理解することで、

Linuxドライバ開発モジュールおよびhelloカーネルモジュールの例のMakefileを理解することで、

  
が説明されます。

単純なドライバモジュールの場合、以下はMakefileの標準的な構成です。
//------------ Makefile ---------------------- obj-m:= hello.o KERNELDIR:= /lib /modules /$(シェルのuname -r)/build PWD: = $(シェルPWD)モジュール:$(MAKE)-C $(KERNELDIR)M = $(PWD)modules_install:$(MAKE)-C $(KERNELDIR)M = $(PWD)は、#は、フロントタブmodules_installことに注意しなければならないモジュール#注意しなければならないフロントタブ

個々の文以下の分析:
OBJ-M:= hello.o

フレーズがモジュールから特定のファイルを有することが意図されてhello.oを必要としますhello.ko
ログインKERNELDIR :. = /LIB /モジュール/$(シェルのunameの-r)/ビルド
ログイン
本明細書で定義されるために構成された構成モジュール名は、可変KERNELDIRありますそして、割り当ては「/lib /modules /$(shell uname -r)/build」です。
この値で説明する唯一のものは$(shell uname -r):


です。ターミナルに$:uname -rと入力してみてください。間違っていると、このコマンドは現在のカーネルのバージョン番号を取得するでしょう。例えば、2.6.38.2などです。
次に、「/lib /modules」ディレクトリのファイルを調べます。


$:ls /lib /modules /

結果は

<です。 Br> 2.6.38.2 2.6.38-8-generic

そのため、&lib; /lib /modules /$(シェルのuname -r)/build'の意味はすでに明らかです。現在のカーネルのソースコードディレクトリ

PWD:= $(シェルPWD)

KERNELDIRは、私はこれを言っているわけではないと信じて、説明してきた、現在のディレクトリを取得することです。つまり、シェルでは、$(shell xxx)は端末でxxxコマンドを実行するのと同じです。

$(MAKE)-C $(KERNELDIR)M = $(PWD)モジュール

これはコンパイルモジュールです:最初にディレクトリを-Cオプションで指定された場所に変更します(すなわち、上部コアのmakefileを保持するカーネルソースディレクトリ); M =目標前にソースディレクトリモジュール構成モジュールに戻るメイクファイルオプションがあり、その後、moduelesはモジュールOBJ-Mのセット変数をターゲットと、上記例では、この変数をhello.oに設定しています。
/:ldd3のP29ページに
ログイン

PS
ログイン

;(&Mdash ldd3のP29引用)、メイクファイルが述べ、その一例があります/Makefileの簡単なOBJ-M:= hello.o

が、変換モジュール、次のコマンドを使用します。
$:-C〜/カーネル2.6メートル= 'のPWD' モジュール

ここ"します。 〜/kernel-2.6"はどこに置くかによって、カーネルソースツリーのディレクトリなので、ネイティブ環境のコマンドは次のようになります。
$:make -C /usr/src/linux-source-2.6 38 M = $ PWDモジュール

最終結果は最初の方法とまったく同じです。

それでは、これらの2つの方法を比較してみましょう知っている可能性があり、実際には、それらの間の唯一の違いは、それぞれ、ソースディレクトリと同じではありません、" /libに/モジュール/$(シェルのuname -rと)/構築"そして" /usr/src/linux-source-2.6.38/"が、あなたは、カーネルをコンパイルした場合は、解凍して、ソースコードは、通常usrディレクトリの下に、私たち自身のダウンロードであることを、知っている、とlibディレクトリになりますされますコンパイル時に過去を自動的にコピーします。2つのファイル構造はまったく同じです。したがって、make効果がまったく同じであることは驚くに当たりません。
こんにちは、カーネルモジュールの例

C言語を学ぶとき、私たちはこんにちは、世界のプログラムを学びます。感じる冗長である:
C ++の#include<ためのコードと、stdio.hの>

  • int型のmain(){

  • のprintf('こんにちは、世界/N')
    return 0;
  • }

    生徒に2つの質問について考えてもらいます。なぜmain()関数を書く必要があるのですか。カーネルCプログラムはmainが必要ですか?

    こちら#include< stdio.h>はprintf()を使用するためのものですが、実際にはすべてC言語ライブラリの関数ですが、カーネルプログラムで使用できますか。

    C言語アプリケーションは、アプリケーションのエントリポイントであるため、main()関数を持っている必要があります。必須です。カーネルモジュールにはカーネルモジュールがあるので、Cアプリケーションにはアプリケーション仕様があります。したがって、カーネルモジュールフレームワークを書くときは、これがルールであることを忘れないでください。

    2番目の質問については、より重要です:あなたは覚えていれば、我々はfopenを言った、アプリケーションは、C言語の標準ライブラリの関数を呼び出すことができ、カーネルは絶対に不可能となり、オープンシステムコールに依存していますそして、システムコールはカーネルエクスポートです、そして、もし我々がカーネルプログラムで標準的な関数ライブラリを使用することができるならば、それは「むしろ」鶏肉または卵子に転送されます。

    次のプログラムはLinuxカーネルモジュールの標準フレームワークです(私が最初に学んだときに先生がこのコードを書いた方法を見てください)。リナックス/module.h>

  • の#include<リナックス/init.h>
    の#include<リナックス/kernel.hを> //のprintkを使用し、必要とする#include<のためのC ++コード
    このファイルを含める
  • MODULE_LICENSE('デュアルBSD /GPL'); MODULE_AUTHOR
    (' stephanxu @ eetek');
  • MODULE_DESCRIPTION('最初のカーネルモジュール')< BR>静的INT __init hello_init(ボイド)
  • {0を返す
    ;
  • }
    静的ボイド__exitのhello_exit(ボイド)
  • {}

  • module_init(hello_init);
    module_exit(hello_exit);




    これはHelloです。私たちはハロープリントアウト達成する必要がある場合は、フレームカーネルモジュール、カーネル、我々は唯一のようhello_initを変更する必要があります:static int型__init hello_init(無効){のprintk('こんにちは、カーネル/N'); 0を返す;}モジュールフレーム次の4つの部分で構成されています。

    (1)ロード時にモジュールが実行する必要があるmodule_init(関数)、およびmodule_init ()Module_exit機能を指定し、で定義されている(機能)だけでなく、module_exit(機能)でのアンインストール時に実行モジュール。あなたはmodule_exit()を使用して宣言すると、そのモジュールは、動的アンインストール機能を持​​っていません。

    (2)module_init()で呼び出される初期化関数と、module_exit()で使用されるクリーンアップ関数を定義する必要があります。初期化関数が負でない値を返す場合にのみ(カーネルでは負の値は操作が失敗したことを示すため)、カーネルモジュールは正しくロードできます。そうでなければモジュールはロードできません。 cleanup関数はvoid型を返します。一般に、初期化関数はモジュールがロードされたときにリソースを要求するために使用され、クリーンアップ関数はモジュールがアンロードされたときにリソースを解放するために使用されます。これはC ++のコンストラクタおよびデコンストラクタに似ています。

    (3)カーネルモジュール用のヘッダファイルは、< linux /module.h>および< linux /init.h>を使用する必要があります。 <>はヘッダーファイルをインクルードするために使用されることに注意することは重要ですが、前述のようにカーネルモジュールは標準ライブラリを参照できないため、これらのヘッダーファイルのどちらも標準関数のヘッダーにはなりません。機能ここのヘッダファイルは実際にはLinuxカーネルソースパスの下の$(KERNELSRC)/includeディレクトリから来ています。

    (4)MODULE_XXXで表される関連コンテンツ、これらは現在のカーネルモジュールの説明ですが、必須ではありませんが、一般的に、いくつかの項目、特にモジュールのライセンス問題を記入してください。 。もちろん、それはまたあなた自身のために名前を作る機会をあなたに与えます、そしてまたあなたは責任があるべきです。モジュールの詳細な説明は、後でエラーをデバッグするのに役立ちます。 Modinfoを使用すると、モジュールをすばやく識別できます。必要に応じて、LDDを参照してください(<<<<>>>"""""""

  • Copyright © Windowsの知識 All Rights Reserved