Dynamic Kernel Module Support (Русский)
Из Википедии:
- Dynamic Kernel Module Support(DKMS) — это фреймворк, который используется для генерации тех модулей ядра Linux, которые в общем случае не включены в дерево исходного кода. DKMS позволяет драйверам устройств автоматически пересобираться, когда ядро уже установлено.
Contents
Преимущества и недостатки
Преимуществом использования DKMS является то, что модули можно будет пересобрать после обновления ядра. Это означает, что пользователь может не ждать, пока какая-то компания, проект или сопроводитель пакета выпустит новую версию модуля.
Недостатком использования DKMS является то, что DKMS портит базу данных Pacman. Проблема в том, что конечные модули больше не принадлежат какому-то пакету, поэтому Pacman не может их отследить. Однако, теоретически такая поддержка может быть добавлена с помощью перехватчиков (хуков) (смотрите: FS#2985).
Установка
Установите dkms из официальных репозиториев.
Включите службу dkms
, чтобы модули DKMS пересобрались автоматически после перезагрузки, если требуется.
Значительное число модулей, которые не включены в ядро имеют DKMS вариант; некоторые из них размещаются в официальных репозиториях, но большинство из них можно найти только в AUR. Ниже перечислены пакеты, которые имеют DKMS версию:
- AMD Catalyst: catalyst-dkmsAUR
- NVIDIA:
- VirtualBox, раздел VirtualBox#Хосты, работающие со сторонним ядром
- VMware, раздел VMware#Using DKMS to manage the modules
Обновления
Модули обычно способны пересобираться через значительное количество обновления ядра, но время от времени нужно обновлять пакет. Для того чтобы следовать изменениям в ядре, исправить ошибки или добавить необходимый функционал следует обновить пакет DKMS перед перезагрузкой.
Использование
Использование DKMS вручную.
Завершения слов по клавише Tab
будет доступно после выполнения команды:
- 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 удален, то информация о предыдущих файлах сборки модуля теряется. В этом случае, перейдите в директорию /usr/lib/modules/ВЕРСИЯЯДРА-АРХИТЕКТУРА
и удалите файлы и папки, которые больше не используются.
Создание DKMS пакета
Здесь приведены некоторые рекомендации, которым необходимо следовать при создании пакета DKMS.
Название пакета
Пакеты DKMS обозначают приписыванием "-dkms" к исходному названию пакета.
Переменная $_pkgname
часто используется после $pkgname
, чтобы описать название пакета без "-dkms" (например, _pkgname=${pkgname%-*}
). Это полезно для того, чтобы сохранялось сходство между исходным PKGBUILD пакета и его DKMS вариантом.
Зависимости
Зависимости должны наследоваться от оригинального пакета с добавлением dkms и удалением linux-headers (так как он указан в пакете dkms как необязательный).
Построение директории для исходных файлов
Сборка исходных файлов должна происходить в (сборочная директория 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 }