非カーネルヘッダーを含むLinuxカーネル(2.6)モジュールのコンパイル
-
03-07-2019 - |
質問
カーネル以外のインクルードによって定義された機能を含むlinux kernel(2.6)モジュールをコンパイルすることは可能ですか?
例:
kernelmodule.h
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> // printk()
// ...
#include <openssl/sha.h>
// ...
メークファイル
obj-m := kernelmodule.o
all:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` clean
$(RM) Module.markers modules.order
私が書いてコンパイルしようとしているカーネルモジュールには、多くのopensslインクルードファイルにある機能が含まれています。
上記の標準メイクファイルでは、Linuxヘッダー以外のインクルードは許可されていません。この機能を含めることは可能ですか?その場合、正しい方向を教えてください。
ありがとう、 マイク
解決
カーネルはユーザー空間コードを使用できず、スタンドアロンである必要があります(つまり、完全に自己完結型であり、ライブラリはありません)。したがって、カーネルは標準ヘッダーを取得しません。
ユーザー空間ヘッダーを取得しようとするメリットが何であるかは明確ではありません。そこに使用することが有効なものがある場合(定数、ユーザー空間関数を呼び出さないマクロがおそらく提供されます)、それらを複製し、必要なカーネル互換部分のみを含めることをお勧めします。
ユーザー空間用に設計されたライブラリとカーネルをリンクすることはできません-たとえそれらがOS呼び出しを行わなくても-カーネル内のリンク環境はそれらを選択できないためです。
代わりに、カーネルで使用する関数を再コンパイルします(OSやライブラリの呼び出し(mallocなど)を行わないと仮定します。この場合、いずれにしても変更する必要があります)。カーネルモジュールで使用する独自のライブラリにそれらを組み込みます。
最近のバージョンのLinuxには、さまざまなSHAハッシュを含む暗号化機能が含まれています-代わりにいずれかを使用できます。
別のアイデアは、カーネル空間で暗号化を行うのをやめて、コードをユーザー空間に移動することです。ユーザースペースのコードは、記述/デバッグ/保守などが簡単です。
他のヒント
私が書いたユーザースペースコードを少し取って、それをカーネルスペースで動作するように変換しました(つまりkmalloc()などを使用して)、それほど難しくはありません。ただし、ユーザー空間ではなくカーネルのCの理解に限定されます。これは、特にさまざまな標準int型でわずかに異なります。
ユーザー空間のDSOに対して単にリンクすることはできません&#8212; Linuxカーネルはモノリシックで、完全に自己完結型です。他の人が指摘したように、ユーザースペースlibc、ライブラリ、またはその他のビットを使用しません。
9/10回、必要なものがカーネルのどこかでどこかに見つかります。他の誰かがあなたと同じニーズに遭遇して、あなたが望むことをするためにいくつかのモジュールにいくつかの静的関数を書いた可能性が非常に高いです。それらをつかんで再利用するだけです。
暗号の場合、他の人が言ったように、カーネルにあるものを使用してください。注意することは、kconfigでそれらを有効にする必要があることです。これは、ビルド時にユーザーが選択した内容によって発生する場合と発生しない場合があります。そのため、依存関係に注意し、明示的に、モジュールの選択時に必要な暗号化APIも選択するkconfigのいくつかのエントリをハッキングする必要がある場合があります。木から構築する場合、それを行うのは少し苦痛になる可能性があります。
そのため、一方では「全体を肥大化させながらコピーして名前を変更する」だけで、もう一方では「完全なカーネルソースを持っている必要がある」と人々に伝えます。これは、モノリシックカーネルに付属する癖の1つです。
Microkernelを使用すると、ほとんどすべてがユーザー空間で実行され、一部のドライバーのDSOにリンクする心配はありません...それは問題ではありません。コメントでカーネル設計の哲学を再開するための手がかりとしてその文を受け取らないでください。それはこの質問の範囲内ではありません。