Linux ドライバー開発のためのカーネル モジュール開発 (2) - カーネル モジュールのコンパイル Makefile を始める

転載元: http://blog.csdn.net/zqixiao_09/article/details/50838043

1. モジュールのコンパイル

       前回のカーネルコンパイルのドライバー移植の部分で、ドライバーのコンパイルが静的コンパイル動的コンパイルに分けられ、静的コンパイルはドライバーを直接カーネルにコンパイルするもの、動的コンパイルはドライバーをモジュールにコンパイルするものであると述べました。

動的コンパイルには 2 つのタイプがあります。

a -- 内部コンパイル

       カーネルソースディレクトリでコンパイルする

b -- 外部コンパイル

       カーネルソースディレクトリの外でコンパイルする

 

第二に、具体的なコンパイルプロセスの分析   

        注: このコンパイルは外部コンパイルであり、使用されるカーネル ソース コードは開発ボードで使用される Linux 3.14 カーネル ソース コードではなく Ubuntu ソース コードであり、オペレーティング プラットフォームは X86 です。

        通常の Linux デバイス ドライバー モジュールの場合、次は古典的な Makefile コードです。次の Makefile を使用すると、ほとんどのドライバーのコンパイルを完了できます。これを使用する場合、コンパイルおよび生成されるドライバーの名前を変更するだけで済みます。obj-m の値を変更するだけです。

 

ifneq ($(KERNELRELEASE),)

obj-m:=こんにちは。o

それ以外

KDIR := /lib/modules/$(shell uname -r)/build

PWD:=$(シェルパスワード)

全て:

    make -C $(KDIR) M=$(PWD) モジュール

綺麗:

    rm -f *.ko *.o *.symvers *.cmd *.cmd.o

エンドイフ

 

 

1. メイクファイル内の変数

    まず、次の Makefile 内のいくつかの変数の意味を説明します。

(1) KERNELRELEASE は、            Linux カーネル ソース コードの最上位の Makefile で定義されています。

(2) Shell pwd は                             現在の作業パスを取得します

(3) シェル uname -r は                    現在のカーネルのバージョン番号を取得します。

(4) KDIR                                     現在のカーネルのソース コード ディレクトリ。

Linux ソース コードに関するディレクトリは 2 つあります。

 "/lib/modules/$(shell uname -r)/build"

"/usr/src/linux-header-$(shell uname -r)/"

       ただし、カーネルをコンパイルしたことがある場合は、usr ディレクトリ内のソース コードは通常、自分でダウンロードして解凍されますが、lib ディレクトリ内のソース コードはコンパイル中に自動的にコピーされることがわかります。この 2 つのファイル構造は、まったく同じです。同じなので、場合によってはカーネル ソース ディレクトリを /usr/src/linux-header-$(shell uname -r)/ に設定します。カーネル ソース コード ディレクトリは、独自の保存場所に応じて変更できます。

(5)make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) モジュール

これはモジュールをコンパイルするものです:

a -- まず、ディレクトリを -C オプションで指定された場所 (つまり、カーネル ソース コード ディレクトリ) に変更します。ここには、カーネルのトップレベルのメイクファイルが保存されます。

b - - M= オプションは、モジュール ターゲットを構築する前に makefile をモジュール ソース コード ディレクトリに戻します。その後、モジュール ターゲットは obj-m 変数に設定されたモジュールを指します。上の例では、変数を次のように設定します。こんにちは。o。

 

2. makeの実行手順

a --初めて入力するときは、マクロ「KERNELRELEASE」が定義されていないため、else を入力します。

b -- カーネル パスと現在のパスを記録します。

       make の背後にはターゲットがないため、make は Makefile 内の . で始まらない最初のターゲットをデフォルトのターゲットとして実行します。デフォルトでは、このルールをすべて実行します

c -- make -C $(KDIR) M=$(PWD) モジュールs

    -C Makefile を実行するカーネルのディレクトリを入力します。実行時に KERNELRELEASE が割り当てられます。M=$(PWD) は、現在のディレクトリに戻り、Makefile を再度実行することを意味します。モジュールはモジュールにコンパイルされます

     ここで実際に実行されるのは

     make -C /lib/modules/2.6.13-study/build M=/home/fs/code/1/module/hello/ modules

d -- makefile を再度実行します。KERNELRELEASE に値が設定され、obj-m:=hello.o が実行されます。

     obj-m: hello.o と他のオブジェクト ファイルを hello.ko モジュール ファイルにリンクし、コンパイル時に最初に hello.c を hello.o ファイルにコンパイルすることを意味します。

 

ここで make が 3 回呼び出されていることがわかります

   1) -- make
   2) -- Linux カーネル ソース ツリーのトップレベルの makedile が呼び出され、生成されます。o ファイル
   3) -- Linux カーネル ソース ツリーの makefile 呼び出し、.o ファイルを ko ファイルにリンクします。

 

3. 複数のファイルをコンパイルする

ソース ファイルが複数ある場合は、次の方法を使用します。

obj-m := こんにちは。

hello-objs := file1.o file2.o file3.o

 

3. 内部コンパイルの簡単な手順

        hello モジュールをカーネル ソース コードに移動した場合。例えば/usr/src/linux/driver/に置くとKERNELRELEASEが定義されます。

     /usr/src/linux/Makefile には、KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION) があります。

この時点で、hello モジュールは make 単独でコンパイルされるのではなく、カーネル内の make モジュールと一緒にコンパイルされるようになり、ドライバー モジュールもカーネルでコンパイルされます。

おすすめ

転載: blog.csdn.net/g1093896295/article/details/82813859