サードパーティ製の独自のドライバーモジュールをコンパイルしようとしていますが、失敗します。 _linux-headers-5.4.0
_パッケージをインストールしましたが、それを正常に使用するgccコマンドラインの記述方法がわかりません。
最小限の例として、_test.c
_を検討してください。これは、文字どおりカーネルヘッダーを含むだけです。
_#include <asm/linkage.h>
#include <linux/module.h>
_
カーネルにはこれらのファイルの両方が含まれており、それ自体をコンパイルできるため、_test.c
_コンパイルが発生するGCCフラグの組み合わせが必ずあるはずです。プロプライエタリドライバーの_.c
_ファイルには、これらのファイルの両方が含まれていますが、私の問題を示すのに十分です。
_eyes=(
-I/usr/src/linux-headers-5.4.0-21/include # for linux/module.h
-I/usr/src/linux-headers-5.4.0-21/Arch/x86/include # for asm/linkage.h
)
gcc -c "${eyes[@]}" test.c
_
結果は
_In file included from /usr/src/linux-headers-5.4.0-21/include/linux/seqlock.h:36,
from /usr/src/linux-headers-5.4.0-21/include/linux/time.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/stat.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:10,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/spinlock.h:60:10: fatal error: asm/mmiowb.h: No such file or directory
60 | #include <asm/mmiowb.h>
| ^~~~~~~~~~~~~~
_
_dpkg -L linux-headers-5.4.0-21 | grep mmiowb.h
_は、このファイルを_include/asm-generic
_および_Arch/{ia64,mips,powerpc,riscv,sh}/include/asm
_で表示します。これらの1つを含めるように_-I
_をさらに調整すると、エラーは次のように移動します。
_In file included from /usr/src/linux-headers-5.4.0-21/include/linux/mmzone.h:19,
from /usr/src/linux-headers-5.4.0-21/include/linux/gfp.h:6,
from /usr/src/linux-headers-5.4.0-21/include/linux/umh.h:4,
from /usr/src/linux-headers-5.4.0-21/include/linux/kmod.h:9,
from /usr/src/linux-headers-5.4.0-21/include/linux/module.h:13,
from test.c:2:
/usr/src/linux-headers-5.4.0-21/include/linux/page-flags-layout.h:6:10: fatal error: generated/bounds.h: No such file or directory
6 | #include <generated/bounds.h>
| ^~~~~~~~~~~~~~~~~~~~
_
そしてthisファイルは単に私のシステムに存在しませんが、_/usr/src/linux-headers-5.4.0-21/KBuild
_と呼ばれるファイルがあり、それを作成するメイクファイルのように見えますが、このメイクファイルを呼び出す方法はわかりません。
ここでどうすればいいですか? _linux-headers-*
_をインストールした後、generated
フォルダにデータを入力するために実行する必要があるコマンドはありますか?この種のものをオンラインでどこかにガイドしますか?
Linuxカーネルにはmake
に基づく独自のビルドシステムがあり、カーネルコンポーネントとモジュールを正常にコンパイルするための正しいgcc
オプションが生成されます。外部カーネルモジュールに含まれるKbuild
ファイルは、そのカーネルビルドシステムで使用するためのものです。さらに、外部カーネルモジュールには、カーネルビルドシステムを呼び出すMakefile
も含める必要があります。外部モジュールの最小のMakefile
は次のようになります。
_obj-m = foo.o
KVERSION = $(Shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
_
ご覧のとおり、カーネルビルドシステムのメインMakefile
は実際には/lib/modules/$(KVERSION)/build
フォルダーにあります。ここで、$(KVERSION)
はビルドしているカーネルのバージョン番号ですために。興味があれば、Makefileのメッシュが何をするのか、最終的にgcc
を呼び出すオプションのセットをたどることができます。