web-dev-qa-db-ja.com

カーネルヘッダーに対してコンパイルする方法は?

サードパーティ製の独自のドライバーモジュールをコンパイルしようとしていますが、失敗します。 _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フォルダにデータを入力するために実行する必要があるコマンドはありますか?この種のものをオンラインでどこかにガイドしますか?

2
Dan

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を呼び出すオプションのセットをたどることができます。

3
Tilman