Dynamic Kernel Module Support

提供: ArchWiki
2021年6月23日 (水) 11:10時点におけるKusanaginoturugi (トーク | 投稿記録)による版 (序文を修正)
ナビゲーションに移動 検索に移動

Wikipedia より:

Dynamic Kernel Module Support (DKMS) はカーネルのソースツリーの外にソースが存在する Linux カーネルモジュールの生成を可能にするプログラム/フレームワークです。新しいカーネルがインストールされたときに DKMS モジュールは自動的にリビルドされます。

これはユーザーが会社・プロジェクト・パッケージメンテナが新しいバージョンのモジュールをリリースするのを待つ必要がないということを意味します。Pacman#フックが導入されたことで、カーネルがアップグレードされたときにモジュールのリビルドは自動的に処理されるようになっています。

インストール

dkms パッケージをインストールしてください。また、使用しているカーネルにあったヘッダーをインストールしてください (標準カーネルの場合 linux-headers です)。

カーネルのソースツリーの外にあるモジュールについてはかなりの数の DKMS のパッケージが作られています。いくらかは 公式リポジトリ にも存在しますが、ほとんどのモジュールは AUR にあります。以下のリストは DKMS のモジュールが存在するソフトウェアパッケージのひと握りです (wiki のページに DKMS についてのセクションがある場合はそのリンクを付しています):

アップグレード

ノート: Pacman は DKMS モジュールをリビルドする際に依存関係を解決しません。DKMS モジュールが他のモジュールに依存する場合、ビルドが失敗する可能性があります (例: zfs-dkmsAUR)。詳しくはバグレポート FS#52901 を参照してください。dkms-sortedAUR[リンク切れ: パッケージが存在しません] パッケージをインストールすることで依存関係の実験的なサポートが追加されます。技術的には `dkms` パッケージが完全に代替されます。DKMS モジュールをインストールする前に dkms-sorted のインストールを試すことができます。

大抵はカーネルのアップグレード時に DKMS モジュールのリビルドが行われますが、リビルドが失敗する可能性がときどきあります。pacman の出力をよく見てください。起動するのに DKMS モジュールに依存している環境の場合や公式リポジトリに存在しないカスタムカーネルで DKMS を使用する場合は特に重要です。

カーネルの変更に対処したり、バグを修正したり、必要な機能を追加するため、再起動する前に DKMS パッケージをアップグレードするようにしてください。

使用方法

DKMS を手動で使用する方法です。

タブ補完は次を実行することで使えます:

# source /usr/share/bash-completion/completions/dkms

モジュールの確認

モジュールの現在の状態、バージョンやツリーのカーネルを確認するには:

$ dkms status

モジュールのリビルド

全てのモジュールをリビルド:

# dkms autoinstall

もしくは特定のカーネルのモジュールをリビルド:

# dkms autoinstall -k 3.16.4-1-ARCH

特定のモジュールをビルド (例: 現在使用しているカーネル):

# dkms install -m nvidia -v 334.21

もしくは:

# dkms install nvidia/334.21

全てのカーネルでモジュールをビルドするには:

# dkms install nvidia/334.21 --all

モジュールの削除

モジュールを削除するには (古いモジュールが勝手に削除されることはありません):

# dkms remove -m nvidia -v 331.49 --all

もしくは:

# dkms remove nvidia/331.49 --all

dkms パッケージを削除した場合、モジュールのビルドファイルに関連する情報が消失します。その場合 /usr/lib/modules/KERNELVERSION-ARCH から使用しないファイルやディレクトリを削除してください。

DKMS パッケージの作成

以下は DKMS パッケージを作成するときのガイドラインです。

パッケージの名前

DKMS パッケージは公式のパッケージ名に "-dkms" を加えた名前を付けます。

"-dkms" を削ったパッケージ名を表すのによく $pkgname の下に $_pkgname 変数が使われます (例: _pkgname=${pkgname%-*})。公式パッケージの PKGBUILD と DKMS パッケージの同じ部分を残しておくのに便利です。

依存パッケージ

依存パッケージは元のパッケージから継承するのに加えて、dkms を追加して linux-headers を削除します (dkms パッケージは任意パッケージとして並べられます)。

ビルドソースの場所

ビルドソースは次の場所に配置します (DKMS のデフォルトビルドディレクトリです):

/usr/src/PACKAGE_NAME-PACKAGE_VERSION

パッケージディレクトリ内の、モジュールのビルド方法を記述した DKMS の設定 (dkms.conf) には PACKAGE_NAMEPACKAGE_VERSION 変数を含めます。

  • PACKAGE_NAME - 実際のプロジェクト名 (通常は $_pkgname または $_pkgbase)。
  • PACKAGE_VERSION - $pkgver にするのが慣例です。

パッチ

PKGBUILD または dkms.conf でソースにパッチを適用できます。

.install でモジュールを自動的にロード

モジュールのロードやアンロードはユーザーが行うようにしてください。モジュールがロードされたときにクラッシュする可能性を考慮します。

namcap の出力

どんなパッケージでも一度は namcap (パッケージ内のよくあるミスや標準にないことをしていないか確認します) を通しておくと良いでしょう。ただし、namcap はまだ DKMS 特有のガイドラインに対応していません。

例えば、DKMS はデフォルトで /usr/src/ を使用しますが、Namcap はこのディレクトリを非標準のディレクトリと判断します。

また、カーネルモジュールの依存関係を更新するのに depmod を明示的に呼び出す必要はありません。Pacman はフックによって自動的に DKMS の dkms installdkms remove を実行します。dkms install によって最後に必ず depmod が呼びだれます。dkms installdkms build に依存しており (最新カーネルに対してソースがビルドされます)、さらに dkms builddkms add に依存しています (/var/lib/dkms/<package>/<version>/source から /usr/src/<package> にシンボリックリンクが張られます)。

サンプル

以下はパッケージ名とバージョンにあわせて dkms.conf を編集するサンプルパッケージです。

PKGBUILD

PKGBUILD
# Maintainer: foo <foo(at)gmail(dot)com>
# Contributor: bar <bar(at)gmai(dot)com>

_pkgbase=amazing
pkgname=amazing-dkms
pkgver=1
pkgrel=1
pkgdesc="The Amazing kernel modules (DKMS)"
arch=('i686' 'x86_64')
url="https://www.amazing.com/"
license=('GPL2')
depends=('dkms')
conflicts=("${_pkgbase}")
install=${pkgname}.install
source=("${url}/files/tarball.tar.gz"
        'dkms.conf'
        'linux-3.14.patch')
md5sums=(use 'updpkgsums')

build() {
  cd ${_pkgbase}-${pkgver}

  # Patch
  patch -p1 -i "${srcdir}"/linux-3.14.patch

}

package() {
  # Install
  msg2 "Starting make install..."
  make DESTDIR="${pkgdir}" install

  # Copy dkms.conf
  install -Dm644 dkms.conf "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf

  # Set name and version
  sed -e "s/@_PKGBASE@/${_pkgbase}/" \
      -e "s/@PKGVER@/${pkgver}/" \
      -i "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/dkms.conf

  # Copy sources (including Makefile)
  cp -r ${_pkgbase}/* "${pkgdir}"/usr/src/${_pkgbase}-${pkgver}/
}

dkms.conf

dkms.conf
PACKAGE_NAME="@_PKGBASE@"
PACKAGE_VERSION="@PKGVER@"
MAKE[0]="make --uname_r=$kernelver"
CLEAN="make clean"
BUILT_MODULE_NAME[0]="@_PKGBASE@"
DEST_MODULE_LOCATION[0]="/kernel/drivers/misc"
AUTOINSTALL="yes"

.install

pacman には DKMS フックが実装されており、.install ファイルで DKMS 固有の設定を指定する必要はありません。dkms installdkms remove は自動的に呼び出されます。

Initial ramdisk

In case you've got any kernel modules installed via DKMS that are used in initial ramdisk, e.g. zfs-dkmsAUR, you may want to write a pacman hook to automate the process of regenerating initramfs image(s).

For example, when using linux and mkinitcpio, to update ZFS module after each zfs-dkmsAUR upgrade,

/etc/pacman.d/hooks/90-mkinitcpio-dkms-linux.hook
[Trigger]
Operation=Install
Operation=Upgrade
Operation=Remove
Type=Package
Target=zfs-dkms
Target=linux

[Action]
Description=Update dkms modules in Linux initcpio
Depends=mkinitcpio
When=PostTransaction
NeedsTargets
Exec=/bin/sh -c 'while read -r trg; do case $trg in linux) exit 0; esac; done; /usr/bin/mkinitcpio -p linux'

You may add more targets to the hook and make additional copies of the hook if you've installed other kernels. Note the 90- prefix is necessary to make sure it runs after the DKMS hooks.

参照