転載元: 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 モジュールと一緒にコンパイルされるようになり、ドライバー モジュールもカーネルでコンパイルされます。