# Dynamic Kernel Module Support (Русский)

Из Википедии:

  Dynamic Kernel Module Support(DKMS) — это фреймворк, который используется для генерации тех модулей ядра Linux, которые в общем случае не включены в дерево исходного кода. DKMS позволяет драйверам устройств автоматически пересобираться, когда ядро уже установлено.

## Преимущества и недостатки

Преимуществом использования DKMS является то, что модули можно будет пересобрать после обновления ядра. Это означает, что пользователь может не ждать, пока какая-то компания, проект или сопроводитель пакета выпустит новую версию модуля.

После введения Pacman#Hooks пересборка модулей осуществляется автоматически во время обновления ядра. Смотрите также #Обновления.

## Установка

Установите пакет dkms и заголовочные файлы вашего ядра (linux-headers - заголовочные файлы ядра по умолчанию).

Значительное число модулей, не включенных в ядро, имеют DKMS вариант; некоторые из них размещаются в официальных репозиториях, но большинство из них можно найти только в AUR. Ниже перечислены пакеты, которые имеют DKMS версию:

- AMD Catalyst: catalyst-dkmsAUR
- NVIDIA:
  - nvidia-dkms
  - nvidia-304xx-dkms
  - nvidia-173xx-dkmsAUR
  - nvidia-96xx-dkmsAUR
  - nvidia-grsec-dkmsAUR
- VirtualBox:
  - virtualbox-host-dkms
  - virtualbox-guest-dkms
- VMware, раздел VMware#Using DKMS to manage the modules

## Обновления

Обычно пересборка модулей DKMS во время обновления ядра выполняется бесшовно, но что-то может пойти не так. Следует обратить особое внимание на вывод pacman! Это, в частности, относится к тем системам, которым требуется модуль DKMS для успешной загрузки и/или если вы используете DKMS с ядром не из официальных репозиториев.

Для того, чтобы следовать изменениям в ядре, исправить ошибки или добавить необходимый функционал, подумайте об обновлении соответствующего пакета DKMS перед перезагрузкой.

## Использование

Использование DKMS вручную.

Автозавершение по `Tab` будет доступно после выполнения команды:

    # 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" к исходному названию пакета.

Переменная `$_pkgname` часто используется после `$pkgname`, чтобы описать название пакета без "-dkms" (например, `_pkgname=${pkgname%-*}`). Это полезно для того, чтобы сохранялось сходство между исходным PKGBUILD пакета и его DKMS вариантом.

### Зависимости

Зависимости должны наследоваться от оригинального пакета с добавлением dkms и удалением linux-headers (так как он указан в пакете dkms как необязательный).

### Построение директории для исходных файлов

Сборка исходных файлов должна происходить в (сборочная директория по умолчанию):

    /usr/src/PACKAGE_NAME-PACKAGE_VERSION

В директории, где хранятся пакеты, конфигуратор DKMS говорит DKMS, как построить модуль (`dkms.conf`), включая переменные `PACKAGE_NAME` и `PACKAGE_VERSION`.

- `PACKAGE_NAME` - имя проекта (обычно `$_pkgname` или `$_pkgbase`).
- `PACKAGE_VERSION` - по соглашению это также должно быть `$pkgver`.

### Применение патчей

К исходным файлам можно применить патчи непосредственно в PKGBUILD или через `dkms.conf`.

### Автоматическая загрузка модуля в .install

Загрузку и выгрузку модулей следует оставить пользователю. Учитывая то, что может произойти сбой модуля при загрузке.

### Вывод 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
    }

Совет: Чтобы держать DKMS пакеты ближе к их не DKMS версиям: избегайте загромождения файлов при помощи специфичными для DKMS вещами (например, номера версий, которые нуждаются в обновлении).

## Смотрите также

- Linux Journal: Exploring Dynamic Kernel Module Support

Categories:

- Kernel (Русский)
- Русский