ツリー外部カーネルモジュールなどのツリー内部カーネルモジュールを構築するには?

ツリー外部カーネルモジュールなどのツリー内部カーネルモジュールを構築するには?

使いたいOracle Linux UEK7カーネルしかし、UEK7DRBDを無効にする、我々はそれに大きく依存しています。

しかし、.src.rpm 利用可能したがって、理論的には、kernel-uek-develパッケージを使用して、元の.src.rpmカーネルツリーからツリー外部モジュールにdrbd.koモジュールを構築することが可能です。/lib/modules/$(uname -r)/build

.config1つの方法はRPM全体を調整することですが、rpmbuild -bbOracleの元のカーネルを起動し続けますただdrbd.ko 同じバージョンのカーネルにきちんとロードされるようにモジュールを構築してください。

基本的に、私たちはツリーの外部カーネルモジュールであるかのようにツリー内のカーネルモジュールを構築しようとしています。 (私たちが望む.koのカーネルバージョンは、私たちが使用するカーネルバージョンとまったく同じです。)

質問:

  • .src.rpm提供カーネル用にパブリッシャが元々ビルドしていない特定のカーネルモジュールをビルドする方法は?

答え1

これが私がUEK6でやったことです。

ビルド依存関係をインストールします。

yum group install Development\ Tools -y
yum install kernel-uek-devel kernel-rpm-macros kernel-abi-whitelists -y

LinbitからDRBDソースtarをダウンロードし、rpmを作成します。

DRBD_VER="9.1.11"
curl -LO https://pkg.linbit.com//downloads/drbd/9/drbd-${DRBD_VER}.tar.gz
tar xf drbd-${DRBD_VER}.tar.gz
(cd ./drbd-${DRBD_VER} && make kmp-rpm)

あなたのリビジョンはここにあります: /root/rpmbuild/RPMS/x86_64

独自のカーネルモジュールを構築する際の唯一の問題は、カーネルをアップグレードするたびに(マイナーなアップグレードでも)モジュールを再構築する必要があることです。

答え2

カーネルUEK R7でもほぼ同じように動作しますが、gcc-toolset-11-annobin-plugin-gccをインストールし、sclを有効にするgcc-toolset-11 "make kmp-rpm"でビルドする必要があります。

答え3

これをスムーズに行うには、多くのトラブルシューティングが必要でした。まず、他の回答のこのリンク手順を最初の手順に従ってください。

それでも機能しない場合は、カーネルソースツリーで実行する必要がある次の前提条件を実行する必要があります。

  • zcat /boot/symvers-5.15.0-7.86.6.1.el9uek.x86_64.gz > Module.symvers
  • cp /boot/System.map-5.15.0-7.86.6.1.el9uek.x86_64 System.map
  • cp Module.symvers vmlinux.symvers
  • ./scripts/extract-vmlinux /boot/vmlinuz-5.15.0-7.86.6.1.el9uek.x86_64 > vmlinux

dmesg次に、次のエラーが発生した場合:

module: x86/modules: Skipping invalid relocation target, existing value is nonzero for type 1, loc 00000000fbd7a560, val ffffffffc0b33cf0

.config...その後、ディストリビューションが提供する設定ファイルとファイルを比較する方法に注意を払う必要があります。

私の場合は、私のディストリビューションに含まれていないバージョンをビルドし、drbd.ko同じソースツリーからビルドしたいと思います。まず、distroが提供する設定を、次のようにdistroが提供するLinuxソースツリー(起動したものと同じバージョン)にコピーしました。

cd /usr/src/linux
cp /boot/config-$(uname -r) .config

次に、を実行してmake menuconfigDRBDを有効にしてから終了し、新しい設定をに保存します.config。一部の設定オプションは、Linuxソースツリーの検索に応じてオンまたはオフにすることができます。生成された構成ファイルを、次のようにディストリビューションで提供されている構成ファイルと比較します。

diff -uw /boot/config-$(uname -r) .config

私の構成とディストリビューションが提供する構成との間の関連の違いを次のように段階的に見てみましょう。

-# Linux/x86_64 5.15.0-7.86.6.1.el9uek.x86_64 Kernel Configuration
+# Linux/x86 5.15.0 Kernel Configuration

これには2つの主な違いがあります。最初に目立つ違いは、バージョンが間違っているため、EXTRAVERSION=-7.86.6.1.el9uek.x86_64コマンドラインを通過する必要があることですmake。 2番目の違いは少し明確ではありません。最初の鉱山はですが、x86_642番目の行はx86スキーマタイプをに渡す必要があるためですARCH=x86_64。だから私のmakeコマンドは次のようになります。

make EXTRAVERSION=-7.86.6.1.el9uek.x86_64 ARCH=x86_64 menuconfig

今すぐ保存して再比較すると、バージョンラインが同じであることがわかります。

私の例では、同じコンパイラを使用していますが、コンパイラのバージョンが変更されていないことを確認してください。その場合は、ディストリビューションで使用するのとまったく同じコンパイラをインポートする必要があります。たとえば、

CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2.1.0.1)"

構成に見られる次の違いは、CTFが欠落していることです。

-CONFIG_HAVE_CTF_TOOLCHAIN=y
...
-CONFIG_CTF=y

オラクルが提供する UEK カーネルなので、dtrace有効になっています。 dtraceツールをダウンロードしてインストールすることで、ビルドチェーンはCTFを検出し、構成内の2つの異なるCTFの違いの問題を解決しました。

特定のパッケージをインストールして解決できるいくつかの構成の違いがあるので、ここには次のようにリストします。

dnf install dwarves

  • -CONFIG_PAHOLE_HAS_SPLIT_BTF=y:

dnf install dtrace-devel

  • -CONFIG_DEBUG_INFO_BTF_MODULES=y
  • -CONFIG_PAHOLE_HAS_SPLIT_BTF=y
  • -CONFIG_DEBUG_INFO_BTF_MODULES=y
  • -CONFIG_MODULE_ALLOW_BTF_MISMATCH=y
  • -CONFIG_CTF=y

パッケージもインストールしましたが、binutils-x86_64-linux-gnu.x86_64上記の問題が解決したかどうかはわかりません。私はそれが私のテストの一部だったので言及しました。必ず必要なのではないかもしれませんが、まだわかりません。

DRBDをビルドするコマンドラインは次のとおりです。

make \
  EXTRAVERSION=-7.86.6.1.el9uek.x86_64 \
  ARCH=x86_64 \
  drivers/block/drbd/drbd.ko

ただし、dmesg次の記号エラーが発生します。

drbd: Unknown symbol lc_seq_printf_stats (err -2)
drbd: Unknown symbol lc_get_cumulative (err -2)
drbd: Unknown symbol lc_del (err -2)
drbd: Unknown symbol lc_committed (err -2)
drbd: Unknown symbol lc_get (err -2)
drbd: Unknown symbol lc_try_get (err -2)
drbd: Unknown symbol lc_element_by_index (err -2)
drbd: Unknown symbol lc_create (err -2)
drbd: Unknown symbol lc_try_lock (err -2)
drbd: Unknown symbol lc_destroy (err -2)
drbd: Unknown symbol lc_reset (err -2)
drbd: Unknown symbol lc_is_used (err -2)
drbd: Unknown symbol lc_seq_dump_details (err -2)
drbd: Unknown symbol lc_put (err -2)
drbd: Unknown symbol lc_find (err -2)

diff上記のプロセスで私が見落としたのは、.configDRBDが依存する新しいモジュールです。

+CONFIG_LRU_CACHE=m

これを発見したとき、欠けているシンボルを見つけるためにいくつかのことを行い、カーネルモジュールlib/lru_cache.koもビルドする必要があることがわかりました。以下は、DRBDモジュールを正常にビルドしてディストリビューションで実行されているカーネルにロードされる最終カーネルビルドコマンドラインです。

make \
  EXTRAVERSION=-7.86.6.1.el9uek.x86_64 \
  ARCH=x86_64 \
  lib/lru_cache.ko \
  drivers/block/drbd/drbd.ko

最後に、両方のモジュールを挿入でき、正しく機能しました。

insmod lib/lru_cache.ko
insmod drivers/block/drbd/drbd.ko

これを/lib/modulesディレクトリにコピーして実行すると、depmod正常に使用できるようになります。

cp lib/lru_cache.ko drivers/block/drbd/drbd.ko /lib/modules/$(uname -r)/extra/
depmod -a
modprobe drbd
dmesg | tail

最後に、次のエラーが発生した場合:

Skipping BTF generation for drivers/md/raid456.ko due to unavailability of vmlinux

次に、次のようにディストリビューションvmlinuxバイナリをカーネルソースツリーに抽出する必要があります。

./scripts/extract-vmlinux /boot/vmlinuz-5.15.0-7.86.6.1.el9uek.x86_64 > vmlinux

操作すると、次のように登録されたブロックデバイスが表示されます。

drbd: initialized. Version: 8.4.11 (api:1/proto:86-101)
drbd: srcversion: 98E710E58B3041F3046305B 
drbd: registered as block device major 147

関連情報