Dynamic Kernel Module Support (日本語) - ArchWiki

# Dynamic Kernel Module Support (日本語)

Wikipedia より:

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

## 効果

DKMS を使用するプラス効果はカーネルがアップグレードされるときにモジュールをリビルドできることです。これはつまり会社・プロジェクト・パッケージメンテナが新しいバージョンのモジュールをリリースするのを待つ必要がないということを意味します。

DKMS を使用するマイナス効果は　DKMS は Pacman のデータベースを破壊することです。作成されたモジュールはパッケージに属さないことになり、Pacman はモジュールを追跡できないという問題があります。ただし理論上は、フックを使ってサポートを追加することができます (参照: FS#2985)。

## インストール

公式リポジトリから dkms をインストールしてください。

`dkms` systemd サービスを有効にすればカーネルをアップグレードした後の再起動時に DKMS モジュールが自動的にリビルドされるようになります。

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

- AMD Catalyst: catalyst-dkms;
- NVIDIA: nvidia-dkms, nvidia-304xx-dkms, nvidia-173xx-dkms, nvidia-96xx-dkms;
- VirtualBox, セクション VirtualBox#ホストでカスタムカーネルを使っている場合;
- VMware, セクション VMware#DKMS を使ってモジュールを管理する。

## アップグレード

大抵はカーネルがアップグレードしてもモジュールをリビルドすることができますが、ときどきパッケージのアップグレードが必要になることがあります。カーネルの変更に対処したり、バグを修正したり、必要な機能を追加するため、再起動する前に DKMS パッケージをアップグレードするようにしてください。

## 使用方法

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

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

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

### モジュールのリビルド

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

    # dkms autoinstall -k $(uname -r)

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

    # dkms autoinstall -k 3.16.4-1-ARCH

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

    # dkms install -m nvidia -v 334.21 -k $(uname -r)

もしくは:

    # dkms install nvidia/334.21 -k $(uname -r)

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

    # dkms install nvidia/334.21 --all

### モジュールの削除

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

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

もしくは:

    # dkms remove nvidia/331.49 --all

## 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_NAME` と `PACKAGE_VERSION` 変数を含めます。

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

### パッチ

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

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

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

### namcap の出力

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

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

### サンプル

以下はパッケージ名とバージョンにあわせて `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

      # Build
      msg2 "Starting ./configure..."
      ./configure

      msg2 "Starting make..."
      make
    }

    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

`depmod` の代わりに `dkms install` を使うことができます (`dkms build` に依存しており、さらにそこから `dkms add` が使われます):

    amazing-dkms.install

    # old version (without -$pkgrel): ${1%%-*}
    # new version (without -$pkgrel): ${2%%-*}

    post_install() {
        dkms install amazing/${1%%-*}
    }

    pre_upgrade() {
        pre_remove ${2%%-*}
    }

    post_upgrade() {
        post_install ${1%%-*}
    }

    pre_remove() {
        dkms remove amazing/${1%%-*} --all
    }

Tip: To keep DKMS packages closer to their non-DKMS counterparts: avoid cluttering up package files with DKMS-specific stuff (e.g. version numbers that need updating).

## 参照

- Linux Journal: Exploring Dynamic Kernel Module Support

Category:

- Kernel (日本語)