この組み込みLinuxデバイスがあります。ここにカーネルレベルの機能を追加したいのですが、このために独自のカーネルをコンパイルしたくありません。 (カーネルがロードされず、ユーザースペースに入ると、デバイスはブリックします。ブートローダにアクセスして復元することはできません。現在、カーネルにはkexecサポートがないため、それを使用して独自のカーネルイメージをテストすることはできません。)
デバイスのカーネルはモジュールをサポートしますが、対応する Module.symvers ファイルのコピーはありません。
私の質問:Linuxカーネル用のModule.symversファイルはありませんが、カーネルイメージとそのためにコンパイルされたモジュールがある場合は、不足しているモジュールを作成してそのカーネルに接続できるより多くのモジュールをコンパイルできますか? Symversファイル、何が必要ですか?
デバイスはLinuxカーネルバージョン3.10を実行します。
カーネルイメージ(uImageコンテナ内):https://www.olio.watch/olio-firmware-1.10.220/olio-firmware/uImage
設定(CONFIG_IKCONFIGを介して上記の画像から抽出されます):https://www.olio.watch/3.10.0-g2ae2f33-config
このカーネルと一致するカーネルモジュールがあります。https://www.olio.watch/olio-firmware-1.10.220/olio-firmware/drv2605.ko
答え1
まず、「Module.symversなしでLinuxカーネルモジュールをコンパイルできますか?」という質問に答えるには、次の目的が何であるかを理解する必要がありますModule.symvers
。
Module.symvers
2つの主な目的があります。
1) vmlinux およびすべてのモジュールに対してエクスポートされたすべてのシンボルをリストします。
CONFIG_MODVERSIONS
2)有効になっている場合はCRCを一覧表示します。有効になっていない場合、CONFIG_MODVERSIONS
CRCは0x00000000を読み取ります。
Module.symvers
カーネルのビルド中に生成され、カーネルとコンパイルされたモジュールからエクスポートされたすべてのシンボルが含まれます。各シンボルについて、対応するCRC値も記憶される。 Module.symvers ファイルの構文は次のとおりです。
<CRC> <Symbol> <module>
たとえば、
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
しかし、私たちが持っているなら、Module.symvers
必要なすべてのシンボルが含まれているので、どんなモジュールでも作ることができます。
使用できない場合でも、Module.symvers
このファイルをビルドしたり、別のモジュールから借りて外部モジュールをビルドしたりできます。
通常、外部モジュールをビルドするときは、ビルドシステムはカーネルのシンボルにアクセスして、すべての外部シンボルが定義されていることを確認する必要があります。これは名前付きビルド段階で行われますMODPOST
。このステップでは、Module.symvers
カーネルソースツリーから読み込んでシンボルを取得します。
Module.symvers
外部モジュールが構築されているディレクトリにファイルがある場合は、そのファイルも読み込みます。このステップでは、カーネルに定義されていないすべてのエクスポートされたシンボルを含むMODPOST
新しいファイルが作成されます。Module.symvers
Module.symvers
ファイルが存在しない場合、外部モジュールは他の外部モジュールからエクスポートされたシンボルを使用している可能性があり、未定義のシンボルに対する警告を避けるためにすべてのkbuild
シンボルを完全に理解する必要があります。
このような状況には3つの回避策があります。
1)トップレベルkbuild
ファイルの使用:2つのモジュールがあり、のfoo.ko
記号が必要なbar.ko
場合は、両方のモジュールが同じバージョンでコンパイルされるように共通のトップレベルファイルを使用できます。次のディレクトリレイアウトを検討してください。foo.ko
bar.ko
kbuild
./foo/ <= contains foo.ko
./bar/ <= contains bar.ko
The top-level kbuild file would then look like:
#./Kbuild (or ./Makefile):
obj-y := foo/ bar/
And executing
$ make -C $KDIR M=$PWD
will then do the expected and compile both modules with
full knowledge of symbols from either module.
2) 追加Module.symvers
ファイルの使用: 外部モジュールをビルドすると、Module.symvers
カーネルで定義されていないすべてのエクスポートされたシンボルを含むファイルが生成されます。のシンボルにアクセスするには、bar.ko
bar.koビルドのModule.symversファイルをfoo.koがビルドされたディレクトリにコピーします。モジュールのビルド中に外部モジュールディレクトリのファイルをkbuild
読み込み、ビルドが完了すると、カーネルの一部ではなく定義されたすべてのシンボルの合計を含む新しいファイルが生成されます。Module.symvers
Module.symvers
3) 「make」変数の使用:他のモジュールからコピーすることが実用的でない場合は、KBUILD_EXTRA_SYMBOLS
ビルドファイルにModule.symvers
スペースで区切られたファイルのリストを割り当てることができます。これらのファイルはシンボルテーブルの初期化中にロードされますKBUILD_EXTRA_SYMBOLS
。modpost
詳しくは1