Сборка модулей ядра: различия между версиями

Материал из ALT Linux Wiki
Строка 69: Строка 69:
===Подготовка шаблона===
===Подготовка шаблона===


Для начала нам нужны утилиты для сборки модулей, взять их можно пока только из гита, например отсюда  
Для начала нам нужны утилиты для сборки модулей, взять которые пока можно только из гита, например отсюда:
<code>
<code>
  git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git
  git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git
</code>
</code>
теперь нам нужна копия репозитария с модулями
Теперь нам нужна копия репозитария с модулями:
<code>
<code>
  git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git modules
  git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git modules
</code>
</code>
чтобы скрипты нашли модули, директория с этим репозитарием должна назваться modules
Для того чтобы скрипты нашли модули, директория с этим репозитарием должна назваться modules
в этой директории
в этой директории
<code>
<code>

Версия от 11:42, 2 сентября 2008

Эта статья только написана, поэтому может, и скорее всего содержит ошибки, как фактические, так орфографические, стилистические и пунктационные, не стесняйтесь править.

Введение

Ядро Linux содержит в себе множество кода, поддерживающего ту или иную возможность или оборудование. Основная часть этого кода (обычно это код поддержки процессоров, памяти и других базовых вещей) вкомпилирована в ядро и загружается с ним, а части кода необходимые только части пользователей --- драйверы устройств, поддержка файловых систем, и т.д., собраны в виде модулей. Модули могут подключаться к ядру по команде пользователя (modprobe,insmod) или автоматически при помощи udev, а также быть выгружены либо самим ядром либо командой rmmod.

Большинство модулей находится в пакете ядра, однако иногда по техническим, административным или юридическим причинам некоторые модули выносятся в отдельные пакеты, и, соответственно, собираются отдельно.

О модулях и названиях

Поскольку в репозитарии может быть множество ядер, модули собираются следующим образом. Имеется пакет с исходными кодами модуля, и пакет с модулем, собранным для конкретного ядра. При этом SRPM второго содержит только spec и патчи, а исходные коды получает по сборочным зависимостям. Таким образом, у нас есть пакеты, имена которых:

  • kernel-source-<module> - содержит только исходники
  • kernel-modules-<module>-<flavour> - модуль module, собранный для ядра flavour (например, kernel-modules-nvidia-std-def)

где module - это имя модуля, а flavour - вариант ядра.

Теперь о релизах пакетов с модулями. Поле release заполняется так: alt<module release>.<kernel version>.<kernel release>, где

  • module release - релиз собственно модуля, то есть если мы обновили именно модуль, то это поле изменяется
  • kernel version - версия ядра в формате 65535 * major version + 256 * mid version + minor version, т.е. 2.6.25 = 132633. Не пугайтесь это число рассчитывает скрипт, описанный позже.
  • kernel release - номер релиза пакета с ядром.

К примеру, модуль с nvidia для ядра kernel-image-std-def-2.6.25-alt8 будет называться kernel-modules-nvidia-std-def-173.14.12-alt1.132633.8

Как собрать модуль локально

Данная фаза нужна в первую очередь для тестирования модуля, и, в общем-то, необязательна, но полезна для понимания процесса.

Что нам нужно

Кроме gcc, make и прочих стандартных сборочных вещей нам нужно kernel-headers-modules-<flavour>(ну и всё что от него зависит). Этот пакет содержит ту часть исходных кодов, заголовочных файлов, make-файлов и скриптов которые необходимы для сборки модулей.

Собственно сборка

Скачав и распаковав исходники модуля мы обнаруживаем, что просто make обычно не работает. Проблема в том что для сборки модуля необходима часть ядра, и эту самую часть make ищет по адресу /lib/modules/<currnet kernel version>/build, и не получает доступ туда, потому что собираем мы от пользователя, а собирать от рута это неправильно. Для этого открываем Makefile и ищем переменную, что то вроде KSRC или KERNELSOURCE обычно идёт в начале и содержит в значении /lib/modules. Далее запускаем сборку например make KSRC=/usr/src/linux-2.6.25-std-def. Обычно модуль после этого собирается.

Собранный модуль можно попробовать загрузить insmod или положить его в другим модулям ядра в /lib/modules/<kernelversion> и загрузить modprobe. Если модуль загрузился и работает можно переходить к следующей части.

Как собрать модуль правильно

Почему предыдущий способ неправилен? Потому что недистрибутивен. Для нормальной сборки нам нужны:

  • знание git (крайне желательно хотя бы начальное знание!)
  • умение пользоваться gear и hasher
  • настроенный hasher
  • доступ на git.altlinux.org
  • достаточно терпения

Сборка kernel-source-module

Для начала нам стоит собрать пакет с исходниками модуля. Этот пакет прост, и фактически содержит в себе только упакованные исходники, а его сборка состоит только в запаковке. Для примера лучше взять что нибудь несложное и готовое, например, сделать так:

git clone  git://git.altlinux.org/people/silicium/packages/kernel-source-heci.git
mkdir kernel-source-module
cd kernel-source-module
git init-db
распаковать исходники
git add .
git commit -a -m "version" (ну или вариации)
git branch -m upstream (чтобы потом докладывать)
git checkout -b master
cp ../kernel-source-heci/.gear* .
cp ../kernel-source-heci/*.spec
mv kernel-source-heci.spec kernel-source-module.spec

Редактируем по образу и подобию kernel-source-module.spec - обычно там надо заменить имя модуля, версию, описание и changelog, а сам процесс сборки обычно можно не трогать.

git add .gear *.spec
git commit -a

Далее собираем пакет при помощи gear. В результате в пакете должен оказаться всего один файл, а именно /usr/src/kernel/sources/kernel-source-module.tar.bz2

Обратите внимание на то, что некоторые пакеты с исходниками в своём имени содержат версию, например, kernel-source-heci-5.0.0.31-5.0.0.31-alt1. Это сделано для того, чтобы можно было иметь возможность собирать разные версии ядер с разными версиями модулей. Например, новые модули не собираются с 2.6.18.

Сборка самого модуля

Про шаблоны

Поскольку править спеки каждого пакета с модулями для каждой версии ядра несколько глупо, была разработана схема, при которой для каждого модуля создается шаблон, а специально обученный скрипт подгоняет этот шаблон к конкретному ядру (в том числе вычисляет релиз модуля) и собирает пакет с модулем. Сами шаблоны хранятся в git-репозитории, в котором есть множество веток, ветки с шаблонами называются template/<module>/<distro> где module - это собственно название модуля (например, nvidia) а distro - это то, подо что мы собираем. Обычно это sisyphus, но, поскольку для разных бранчей шаблоны приходиться менять, можно установить поле distro в соответствующее значение. Обычно используется alt-linux-4.0 для branch/4.0 и alt-linux-4.1 для branch/4.1.

Подготовка шаблона

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

git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git

Теперь нам нужна копия репозитария с модулями:

git clone git://git.altlinux.org/people/silicium/packages/kernel-build-scripts.git modules

Для того чтобы скрипты нашли модули, директория с этим репозитарием должна назваться modules в этой директории

git checkout -b template/module/sisyphus template/heci/sisyphus
rm SOURCES/*
mv kernel-modules-heci.spec kernel-modules-module.spec

Теперь редактируем спек, меняем: имя, версию, описания, чейнджлог, возможно надо будет поправить опции для сборки. И коммитим.

add *.spec
git commit -a

Сборка

Теперь в директории kernel-build-scripts запустим скрипт для сборки модулей

./buildmodules --hasher --hsh-workdir=/home/silicium/hasher  -k std-def module

Hint -k <flavour> можно делать несколько раз Hint Сборка модулей на x86_64 под i586 может выгладит так

./buildmodules --hasher --hsh-workdir=/home/silicium/hasher --hsh-options '--apt-conf /home/silicium/i586/apt.conf' --target i586 -k ....

Логи сборки лежат в out/logs/kernel-modules-module-std-def.log.

Соответственно, если оно не получилось, можно посмотреть в логи, при желании зайти внутрь хешеру, попробовать там. Потом пойти в modules поправить спек, сделать

git commit -a --amend

и попробовать ещё раз, пока модуль не собирётся.

Подробнее про опции скриптов buildkernel и buildmodules можно прочитать в README находящийся в kernel-build-scripts.

Как выложить модуль в репозитарий

Для начала у себя в git создать репозитарий и залить kernel-source-modules

ssh git.alt init-db kernel-source-module
cd kernel-source-module
git remote add public ssh://git.alt/people/user/packages/kernel-source-module
git push --all public

Теперь выложим kernel-modules

ssh git.alt clone /people/silicium/packages/kernel-modules
cd kernel-build-scripts/modules
git remote add public ssh://git.alt/people/user/packages/kernel-modules
git remote push --all public

потом, подписать и залить в incoming SRPM пакеты. Важно помнить:

  • Для правильной сборки SRPM с kernel-source-module должен быть собран до сборки kernel-modules-module

    Рекомендации по взаимодействию с мейнтейнирами ядер

    Для нормальной совместной работы рекомендуется:

  • Оповестить мейнтейнеров ядер, о том что есть ваш модуль
  • При обновлении модуля обновлять сборки под максимальное количество ядер
  • Настроить git remote на kernel-modules других мейнтенеров
  • В спеках kernel-modules- поле Packager установить в Kernel Maintainers team
  •