usbhid.ko
用に独自のモジュールを構築しようとしていますが、コンパイルした後、モジュールをロードできません。 dmesg
はno symbol version for module_layout
と言います。何が問題なのでしょうか?私はすでにUbuntuが提供するカーネルソースを使用しており、カーネルバージョンが同じであることも確認しています。
特に問題は、モジュールをビルドしたときに、カーネルソースツリーにおそらく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を好む傾向があります:)
カーネルに対応するlinux-headers
パッケージとlinux-source
パッケージの両方をインストールしてください。たとえば、カーネル3.2.0-27-generic-pae
の場合:
linux-headers-3.2.0-27-generic-pae
および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)
を置き換える必要があります。
cd /usr/src/linux-source-$Version
そして.tar.bz2アーカイブを所定の場所に解凍し、抽出されたディレクトリにcdします-すでにこれを行っていると思いますcp /boot/config-$(uname -r) .config
をカーネルソースディレクトリにcp /usr/src/linux-headers-$(uname -r)/Module.symvers .
をカーネルソースディレクトリにそれが終わったら、カーネルソースディレクトリで次のようにします。
make prepare
make scripts
make M=drivers/usb/serial
-ニーズに合わせてM=
の後にパスを変更します残念ながら、Module.symvers
を変更せずに特定のモジュールをビルドする方法がわかりません。たとえば、make drivers/usb/serial/option.ko
を実行すると、Module.symvers
ファイルが強制終了され、元の問題が発生します。 M=
パラメータを使用しても強制終了されませんが、指定されたパスにあるすべてのモジュールをビルドする必要があります。まだ回避策が見つかりません。
make prepare
を実行する前に、まったく同じカーネル構成を使用する必要があります。また、ツリー外でビルドする場合は、現在実行中のカーネル(またはコンパイル時に実行していない場合はターゲットカーネル)と一致する正確に同一のカーネルヘッダーに対してビルドする必要があります。