Module.symversを使用せずにLinuxカーネルモジュールをコンパイルする

Module.symversを使用せずにLinuxカーネルモジュールをコンパイルする

この組み込み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.symvers2つの主な目的があります。

1) vmlinux およびすべてのモジュールに対してエクスポートされたすべてのシンボルをリストします。

CONFIG_MODVERSIONS2)有効になっている場合はCRCを一覧表示します。有効になっていない場合、CONFIG_MODVERSIONSCRCは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.kobar.kokbuild

    ./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.kobar.koビルドのModule.symversファイルをfoo.koがビルドされたディレクトリにコピーします。モジュールのビルド中に外部モジュールディレクトリのファイルをkbuild読み込み、ビルドが完了すると、カーネルの一部ではなく定義されたすべてのシンボルの合計を含む新しいファイルが生成されます。Module.symversModule.symvers

3) 「make」変数の使用:他のモジュールからコピーすることが実用的でない場合は、KBUILD_EXTRA_SYMBOLSビルドファイルにModule.symversスペースで区切られたファイルのリストを割り当てることができます。これらのファイルはシンボルテーブルの初期化中にロードされますKBUILD_EXTRA_SYMBOLSmodpost

詳しくは1

関連情報