web-dev-qa-db-ja.com

usbhid.koをロードしようとすると、「module_layoutのシンボルバージョンがありません」

usbhid.ko用に独自のモジュールを構築しようとしていますが、コンパイルした後、モジュールをロードできません。 dmesgno symbol version for module_layoutと言います。何が問題なのでしょうか?私はすでにUbuntuが提供するカーネルソースを使用しており、カーネルバージョンが同じであることも確認しています。

26
SpecC

特に問題は、モジュールをビルドしたときに、カーネルソースツリーにおそらくModules.symversファイルがなかったことです。モジュールをビルドすると、kbuildシステムは実際にこれについて警告します。 Modules.symversが欠落している場合、以下が表示されます。

警告:シンボルバージョンダンプ/usr/src/linux-2.6.34-12/Modules.symversがありません。モジュールには依存関係とmodversionはありません。

カーネルでCONFIG_MODVERSIONSが有効になっている場合、ドライバーのビルドのmodpostフェーズで、-mオプションを指定してscripts/mod/modpostを実行します。勇敢でscripts/mod/modpost.c sourceを見ると、-mオプションがvmlinuxから_module_layout_シンボルを追加することがわかりますが、持っていない場合はカーネルからModules.symversを実行すると、このシンボルのCRC値が取得されず、このエラーメッセージが表示されます。

そのため、これには2つの方法があります。

1)実行中のカーネルのフルビルドを実行してModules.symversを生成し、モジュールを再構築します。 [http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt][1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2)もう1つのオプションは、愚かなmodprobeにすべてのがらくたを無視して、とにかくモジュールをロードするように指示することです:

modprobe -f <module>

私はオプション2を好む傾向があります:)

21
Dan Gora

カーネルに対応するlinux-headersパッケージとlinux-sourceパッケージの両方をインストールしてください。たとえば、カーネル3.2.0-27-generic-paeの場合:

  1. linux-headers-3.2.0-27-generic-paeおよび
  2. linux-source-3.2.0-27-generic-pae

上記のパッケージのバージョンが実行中のカーネルバージョンと一致しない場合は、$(uname -r)を上記のインストール済みカーネルパッケージのバージョン文字列に置き換える必要があります。
上記の例では、パッケージのバージョンは3.2.0-27-generic-paeです。 uname -rを実行し、その出力が3.2.0-27-generic-paeと異なる場合、インストールされたパッケージのバージョン文字列と一致するように、以下の各$(uname -r)を置き換える必要があります。

  1. cd /usr/src/linux-source-$Versionそして.tar.bz2アーカイブを所定の場所に解凍し、抽出されたディレクトリにcdします-すでにこれを行っていると思います
  2. cp /boot/config-$(uname -r) .configをカーネルソースディレクトリに
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers .をカーネルソースディレクトリに

それが終わったら、カーネルソースディレクトリで次のようにします。

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial-ニーズに合わせてM=の後にパスを変更します

残念ながら、Module.symversを変更せずに特定のモジュールをビルドする方法がわかりません。たとえば、make drivers/usb/serial/option.koを実行すると、Module.symversファイルが強制終了され、元の問題が発生します。 M=パラメータを使用しても強制終了されませんが、指定されたパスにあるすべてのモジュールをビルドする必要があります。まだ回避策が見つかりません。

15
Radu C

make prepareを実行する前に、まったく同じカーネル構成を使用する必要があります。また、ツリー外でビルドする場合は、現在実行中のカーネル(またはコンパイル時に実行していない場合はターゲットカーネル)と一致する正確に同一のカーネルヘッダーに対してビルドする必要があります。

1
Daniel T Chen