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

Материал из ALT Linux Wiki
(Викификация, вычитка)
Строка 1: Строка 1:
[[Категория:Devel]]
[[Категория:Devel]]
[[Категория:Sisyphus]]
[[Категория:Sisyphus]]
= Введение =
== Введение ==
Ядро Linux содержит в себе множество кода, поддерживающего ту или иную возможность или оборудование. Основная часть этого кода (обычно это код поддержки процессоров, памяти и других базовых вещей) вкомпилирована в ядро и загружается с ним, а части кода необходимые только части пользователей --- драйверы устройств, поддержка файловых систем, и т.д., собраны в виде модулей. Модули могут подключаться к ядру по команде пользователя (''modprobe'',''insmod'') или автоматически при помощи udev, а также быть выгружены либо самим ядром либо командой ''rmmod''.
Ядро Linux содержит в себе множество кода, поддерживающего ту или иную возможность или оборудование. Основная часть этого кода (обычно это код поддержки процессоров, памяти и других базовых вещей) вкомпилирована в ядро и загружается с ним, а части кода, необходимые только части пользователей — драйверы устройств, поддержка файловых систем, и т. д. — собраны в виде модулей. Модули могут подключаться к ядру по команде пользователя (<tt>modprobe</tt>, <tt>insmod</tt>) или автоматически при помощи udev, а также быть выгружены либо самим ядром, либо командой <tt>rmmod</tt>.


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


== О модулях и названиях ==
== О модулях и названиях ==
Поскольку в репозитарии может быть множество ядер, модули собираются следующим образом. Имеется пакет с исходными кодами модуля, и пакет с модулем, собранным для конкретного ядра. При этом SRPM второго содержит только spec и патчи, а исходные коды получает по сборочным зависимостям.
 
Поскольку в репозитории может быть множество ядер, модули собираются особым способом: имеется пакет с исходными кодами модуля, и пакеты с модулями, собранным для конкретного ядра. При этом SRPM второго содержит только .spec и патчи, а исходные коды получает по сборочным зависимостям.
Таким образом, для модуля ''module'' и варианта ядра ''flavour'' у нас имеются пакеты с именами
Таким образом, для модуля ''module'' и варианта ядра ''flavour'' у нас имеются пакеты с именами
* kernel-source-''module'' - содержит только исходники
* <tt>kernel-source-''module''</tt> — содержит только исходники
* kernel-modules-''module''-''flavour'' - модуль ''module'', собранный для ядра ''flavour'' (например, kernel-modules-nvidia-std-def)
* <tt>kernel-modules-''module''-''flavour''</tt> — модуль ''module'', собранный для ядра ''flavour'' (например, <tt>kernel-modules-nvidia-std-def</tt>)
 
Поле release пакетов с модулями заполняется так: <tt>alt<module release>.<kernel version>.<kernel release></tt>, где
* module release — релиз собственно модуля, то есть если мы обновили именно модуль, то это поле изменяется
* kernel version — версия ядра в формате 65535 * major version + 256 * mid version + minor version, то есть 2.6.25 = 132633. Не пугайтесь, это число рассчитывает скрипт, описанный позже.
* kernel release — номер релиза пакета с ядром.


Теперь о релизах пакетов с модулями. Поле release заполняется так: alt<module release>.<kernel version>.<kernel release>, где
К примеру, модуль с nvidia для ядра <tt>kernel-image-std-def-2.6.25-alt8</tt> будет называться kernel-modules-nvidia-std-def-173.14.12-alt1.132633.8
* module release - релиз собственно модуля, то есть если мы обновили именно модуль, то это поле изменяется
* kernel version - версия ядра в формате 65535 * major version + 256 * mid version + minor version, т.е. 2.6.25 = 132633. Не пугайтесь это число рассчитывает скрипт, описанный позже.
* kernel release - номер релиза пакета с ядром.<br>


К примеру, модуль с 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.
=== Что нам нужно ===
Если модуль загрузился и работает, то можно переходить к следующей части.
 
Кроме gcc, make и прочих стандартных сборочных вещей нам нужно <tt>kernel-headers-modules-<flavour></tt> (и всё что от него зависит). Этот пакет содержит ту часть исходных кодов, заголовочных файлов, make-файлов и скриптов, которые необходимы для сборки модулей для данного ядра.
 
=== Сборка ===
 
Скачав и распаковав исходники модуля, мы обнаружим что просто <tt>make</tt> обычно не работает. Эта проблема специфична для Sisyphus/ALT Linux и состоит в том, что для сборки модуля необходимы заголовки ядра, которые ищутся в пути<tt>/lib/modules/<currnet kernel version>/build</tt>, но не могут быть найдены там, потому что в ALT Linux и Sisyphus доступ пользователям в <tt>/lib/modules/<tt> запрещён.
 
Для того, чтобы обойти эту проблему, нужно переопределить переменную (обычно <tt>KERNELSOURCE</tt> или <tt>KSRC</tt>) в Makefile. Далее запускаем сборку, например <tt>make KSRC=/usr/src/linux-2.6.25-std-def</tt>. Обычно модуль после этого собирается.
 
Собранный модуль можно попробовать загрузить с помощью <tt>insmod</tt> или положить его к другим модулям ядра в <tt>/lib/modules/<kernelversion></tt> и загрузить modprobe. Если модуль загрузился и работает, то можно переходить к следующей части.


= Как собрать модуль правильно =
== Как собрать модуль правильно ==
Почему предыдущий способ неправилен? Потому что недистрибутивен. Для нормальной сборки нам нужны:
Почему предыдущий способ неправилен? Потому что недистрибутивен. Для нормальной сборки нам нужны:
* знание [[git]] (крайне желательно хотя бы начальное знание!)
* знание [[git]] (крайне желательно хотя бы начальное знание!)
Строка 36: Строка 43:
* доступ на git.altlinux.org (для публикации результатов)
* доступ на git.altlinux.org (для публикации результатов)
* достаточно терпения
* достаточно терпения
== Сборка kernel-source-module ==
== Сборка kernel-source-module ==
Для начала нам стоит собрать пакет с исходниками модуля. Этот пакет прост, и фактически содержит в себе только упакованные исходники, а его сборка состоит только в запаковке. Для примера лучше взять что нибудь несложное и готовое, например, сделать так:
Для начала нам стоит собрать пакет с исходниками модуля. Этот пакет прост, и фактически содержит в себе только упакованные исходники, а его сборка состоит только в запаковке. Для примера лучше взять что нибудь несложное и готовое, например, сделать так:
Строка 52: Строка 60:
  mv kernel-source-heci.spec kernel-source-''module''.spec
  mv kernel-source-heci.spec kernel-source-''module''.spec
</code>
</code>
Редактируем по образу и подобию kernel-source-''module''.spec - обычно там надо заменить имя модуля, версию, описание и changelog, а сам процесс сборки обычно можно не трогать.
Редактируем по образу и подобию kernel-source-''module''.spec — обычно там надо заменить имя модуля, версию, описание и changelog, а сам процесс сборки обычно можно не трогать.
<code>
<code>
  git add .gear *.spec
  git add .gear *.spec
Строка 64: Строка 72:


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


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


Для начала нам нужны утилиты для сборки модулей, взять которые пока можно только из гита, например отсюда:  
Для начала нам нужны утилиты для сборки модулей, взять которые пока можно только из гита, например отсюда:
<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
Строка 89: Строка 97:
</code>
</code>


===Сборка===
=== Сборка ===


Теперь в директории kernel-build-scripts запустим скрипт для сборки модулей
Теперь в директории kernel-build-scripts запустим скрипт для сборки модулей
Строка 95: Строка 103:
  ./buildmodules --hasher --hsh-workdir=/home/silicium/hasher  -k std-def ''module''
  ./buildmodules --hasher --hsh-workdir=/home/silicium/hasher  -k std-def ''module''
</code>
</code>
'''Hint''' -k ''flavour'' можно делать несколько раз <br>
'''Hint''' -k ''flavour'' можно делать несколько раз <br />
'''Hint''' Сборка модулей на x86_64 под i586 может выгладит так
'''Hint''' Сборка модулей на x86_64 под i586 может выгладит так
<code>
<code>
Строка 120: Строка 128:
</code>
</code>


Теперь выложим kernel-modules  
Теперь выложим kernel-modules
<code>
<code>
  ssh git.alt clone /people/silicium/packages/kernel-modules
  ssh git.alt clone /people/silicium/packages/kernel-modules
Строка 137: Строка 145:
* При обновлении модуля обновлять сборки под максимальное количество ядер
* При обновлении модуля обновлять сборки под максимальное количество ядер
* Настроить git remote на kernel-modules других мейнтенеров
* Настроить git remote на kernel-modules других мейнтенеров
* В спеках kernel-modules- поле Packager установить в Kernel Maintainers team
* В спеках kernel-modules- поле Packager установить в Kernel Maintainers team

Версия от 14:28, 5 сентября 2008

Введение

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

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

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

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

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

Поле 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 обычно не работает. Эта проблема специфична для Sisyphus/ALT Linux и состоит в том, что для сборки модуля необходимы заголовки ядра, которые ищутся в пути/lib/modules/<currnet kernel version>/build, но не могут быть найдены там, потому что в ALT Linux и Sisyphus доступ пользователям в /lib/modules/ запрещён.

Для того, чтобы обойти эту проблему, нужно переопределить переменную (обычно KERNELSOURCE или KSRC) в Makefile. Далее запускаем сборку, например 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

Теперь нам нужна копия репозитария с модулями. Для того чтобы скрипты нашли модули, директория, содержащая копию должна назваться modules и содержаться в директории kernel-build-scripts:

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

После этого нам нужно создать новую ветку

git checkout -b template/module/sisyphus origin/template/heci/sisyphus
rm -f 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.koi8 из kernel-build-scripts.

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

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

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