Сборка модулей ядра
Материал из ALT Linux Wiki
(→Сборка) |
|||
Строка 1: | Строка 1: | ||
- | + | ==Модули ядра== | |
- | Ядро Linux содержит в себе множество кода, поддерживающего ту или иную возможность или оборудование. Основная часть этого кода (обычно это код поддержки процессоров, памяти и других базовых вещей) вкомпилирована в ядро и загружается с ним, а части кода, необходимые только части пользователей — драйверы устройств, поддержка файловых систем, и т. | + | Ядро Linux содержит в себе множество кода, поддерживающего ту или иную |
+ | возможность или оборудование. Основная часть этого кода (обычно это код | ||
+ | поддержки процессоров, памяти и других базовых вещей) вкомпилирована в ядро | ||
+ | и загружается с ним, а части кода, необходимые только части пользователей — | ||
+ | драйверы устройств, поддержка файловых систем, и т.д. — собраны в виде модулей. | ||
- | Большинство модулей находится в пакете ядра, однако иногда по техническим, административным или юридическим причинам некоторые модули | + | Модули могут подключаться к ядру по команде пользователя (<tt>modprobe</tt>, |
+ | <tt>insmod</tt>) или автоматически при помощи udev, и быть выгружены либо самим | ||
+ | ядром, либо командой <tt>rmmod</tt>. | ||
+ | |||
+ | Большинство модулей находится в пакете ядра, однако иногда по техническим, | ||
+ | административным или юридическим причинам некоторые модули собираются отдельно. | ||
== О модулях и названиях == | == О модулях и названиях == | ||
- | Поскольку в репозитории может быть множество ядер, модули собираются особым способом: имеется пакет с исходными кодами модуля, и пакеты с модулями, собранным для конкретного ядра. При этом SRPM | + | Поскольку в репозитории может быть множество ядер, модули собираются особым способом: |
- | Таким образом, для модуля ''module'' и варианта ядра ''flavour'' у нас имеются пакеты с именами | + | имеется пакет с исходными кодами модуля, и пакеты с модулями, собранным для конкретного |
+ | ядра. При этом SRPM последних содержит только .spec и патчи, а исходные коды получает по | ||
+ | сборочным зависимостям. Таким образом, для модуля ''module'' и варианта ядра ''flavour'' | ||
+ | у нас имеются пакеты с именами | ||
* <tt>kernel-source-''module''</tt> — содержит только исходники | * <tt>kernel-source-''module''</tt> — содержит только исходники | ||
* <tt>kernel-modules-''module''-''flavour''</tt> — модуль ''module'', собранный для ядра ''flavour'' (например, <tt>kernel-modules-nvidia-std-def</tt>) | * <tt>kernel-modules-''module''-''flavour''</tt> — модуль ''module'', собранный для ядра ''flavour'' (например, <tt>kernel-modules-nvidia-std-def</tt>) | ||
- | Поле release пакетов с модулями заполняется так: <tt>alt< | + | Поле <tt>release</tt> пакетов с модулями заполняется так: <tt>alt<module_release>.<kernel_version>.<kernel_release></tt>, где |
- | * | + | * <tt><module_release></tt> — релиз собственно модуля, то есть, если мы обновили именно модуль, то это поле изменяется; |
- | * | + | * <tt><kernel_version></tt> — версия ядра в формате <tt>65535*major + 256 * mid + minor</tt>, то есть <tt>2.6.25=132633</tt>. Не пугайтесь, это число рассчитывает скрипт, описанный позже; |
- | * | + | * <tt><kernel_release></tt> — релиз пакета с ядром. |
- | К примеру, модуль с nvidia для ядра <tt>kernel-image-std-def-2.6.25-alt8</tt> будет называться <tt>kernel-modules-nvidia-std-def-173.14.12-alt1.132633.8</tt>. | + | К примеру, модуль с <tt>nvidia</tt> для ядра <tt>kernel-image-std-def-2.6.25-alt8</tt> будет называться <tt>kernel-modules-nvidia-std-def-173.14.12-alt1.132633.8</tt>. |
== Как собрать модуль локально == | == Как собрать модуль локально == | ||
Строка 66: | Строка 78: | ||
=== Сборка самого модуля === | === Сборка самого модуля === | ||
- | === | + | === Шаблоны === |
- | Поскольку править спеки каждого пакета с модулями для каждой версии ядра несколько глупо, была разработана схема, при которой для каждого модуля создается шаблон, а | + | Поскольку править спеки каждого пакета с модулями для каждой версии ядра несколько глупо, |
+ | была разработана схема, при которой для каждого модуля создается шаблон, а специальный скрипт | ||
+ | подгоняет этот шаблон к конкретному ядру (в том числе вычисляет релиз модуля) и собирает пакет | ||
+ | с модулем. Сами шаблоны хранятся в git-репозитории, в котором есть множество веток, ветки | ||
+ | с шаблонами называются <tt>template/''module''/''distro''</tt>, где ''module'' — это | ||
+ | собственно название модуля (например, <tt>nvidia</tt>) а ''distro'' — это то, подо что | ||
+ | мы собираем. Обычно это <tt>sisyphus</tt>, но, поскольку для разных бранчей шаблоны | ||
+ | приходиться менять, можно установить поле ''distro'' в соответствующее значение. | ||
+ | Обычно используется <tt>alt-linux-X.Y</tt> для [[branch/X.Y]] (например, <tt>alt-linux-4.1</tt> для [[branch/4.1]]). | ||
+ | |||
+ | === Подготовка рабочей директории === | ||
+ | Нам потребуются утилиты для сборки модулей из пакета <tt>kernel-build-tools</tt>: | ||
+ | # apt-get update && apt-get install kernel-build-tools | ||
+ | Для работы с этими утилитами нужно подготовить рабочую директорию: | ||
+ | $ mkdir ~/build-modules && cd ~/build-modules | ||
+ | $ ln -s <репозиторий с ядром> kernel | ||
+ | $ ln -s <репозиторий с модулями> modules | ||
+ | |||
+ | При поиске репозиториев на git.alt нужно знать, что | ||
+ | * репозитории с модулями обычно называется <tt>kernel-modules</tt> | ||
+ | * репозиторий с ядром обычно называется <tt>kernel-image</tt> | ||
+ | * более старые ядра могут называться <tt>kernel-image-''version''</tt> | ||
+ | |||
+ | Примеры: | ||
+ | $ git clone git://git.altlinux.org/people/silicium/packages/kernel-modules.git | ||
+ | $ git clone git://git.altlinux.org/people/shrek/packages/kernel-image.git | ||
+ | $ git clone git://git.altlinux.org/people/aspsk/packages/kernel-image-2.6.18.git | ||
+ | |||
+ | === Сборка модуля из шаблона === | ||
+ | Сборка модуля из шаблона происходит в рабочей директории. Для сборки модуля ''module'' | ||
+ | под flavour std-def с помощью hasher можно использовать команду | ||
+ | $ buildmodules -k std-def ''module'' | ||
+ | Если хочется собрать такой же модуль под другую архитектуру, например под i586, | ||
+ | то следует использовать команду | ||
+ | $ buildmodules --target i586 --hsh-options='--apt-conf .../i586/apt.conf' -k std-def ''module'' | ||
+ | где <tt>.../i586/apt.conf</tt> — соответствующий конфигурационный файл для apt. | ||
+ | |||
+ | Если не указывать список модулей, то для каждого указанного ''flavour'' будет | ||
+ | предпринята попытка собрать все модули, указанные в файле <tt>modules.build</tt> | ||
+ | из ядерного бранча <tt>kernel-image-''flavour''</tt>. | ||
+ | |||
+ | Логи сборки складываются в <tt>out/logs/kernel-modules-''module''-''flavour''.log</tt>. | ||
+ | |||
+ | Подробнее про опции скрипта buildmodules (и других) можно прочитать в файле [http://git.altlinux.org/people/aspsk/packages/kernel-build-tools.git?p=kernel-build-tools.git;a=blob;f=README.ru.koi8;hb=HEAD README.ru.koi8] из репозитория <tt>kernel-build-tools</tt>. | ||
+ | |||
+ | === Сборка модулей на git.alt === | ||
+ | При сборке пакета на [git.altlinux.org git.alt] необходимо указать пару (репозиторий, тэг). | ||
+ | Для (полу)автоматического обновления модулей в Сизифе можно использовать скрипт updatemodules. | ||
+ | |||
+ | Для данного темплейта этот скрипт обновляет бранчи для указанных flavour. | ||
+ | Например, команда | ||
+ | $ updatemodules -k ovz-rhel | ||
+ | обновит бранчи для модулей, указанных в файле kernel-image-ovz-rhel:modules.build, | ||
+ | создаст для них подписанные тэги и положит их в файл <tt>out/taglist</tt> | ||
+ | в рабочей директории. | ||
+ | |||
+ | == dead == | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
После этого нам нужно создать новую ветку в репозитории с модулями: | После этого нам нужно создать новую ветку в репозитории с модулями: | ||
<code> | <code> | ||
Строка 93: | Строка 151: | ||
git commit -a | git commit -a | ||
</code> | </code> | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
== Как выложить модуль в репозиторий == | == Как выложить модуль в репозиторий == |
Версия 13:26, 23 июня 2009
Содержание |
Модули ядра
Ядро 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 + 256 * mid + minor, то есть 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.alt (для публикации результатов)
- достаточно терпения
Сборка 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-X.Y для branch/X.Y (например, alt-linux-4.1 для branch/4.1).
Подготовка рабочей директории
Нам потребуются утилиты для сборки модулей из пакета kernel-build-tools:
# apt-get update && apt-get install kernel-build-tools
Для работы с этими утилитами нужно подготовить рабочую директорию:
$ mkdir ~/build-modules && cd ~/build-modules $ ln -s <репозиторий с ядром> kernel $ ln -s <репозиторий с модулями> modules
При поиске репозиториев на git.alt нужно знать, что
- репозитории с модулями обычно называется kernel-modules
- репозиторий с ядром обычно называется kernel-image
- более старые ядра могут называться kernel-image-version
Примеры:
$ git clone git://git.altlinux.org/people/silicium/packages/kernel-modules.git $ git clone git://git.altlinux.org/people/shrek/packages/kernel-image.git $ git clone git://git.altlinux.org/people/aspsk/packages/kernel-image-2.6.18.git
Сборка модуля из шаблона
Сборка модуля из шаблона происходит в рабочей директории. Для сборки модуля module под flavour std-def с помощью hasher можно использовать команду
$ buildmodules -k std-def module
Если хочется собрать такой же модуль под другую архитектуру, например под i586, то следует использовать команду
$ buildmodules --target i586 --hsh-options='--apt-conf .../i586/apt.conf' -k std-def module
где .../i586/apt.conf — соответствующий конфигурационный файл для apt.
Если не указывать список модулей, то для каждого указанного flavour будет предпринята попытка собрать все модули, указанные в файле modules.build из ядерного бранча kernel-image-flavour.
Логи сборки складываются в out/logs/kernel-modules-module-flavour.log.
Подробнее про опции скрипта buildmodules (и других) можно прочитать в файле README.ru.koi8 из репозитория kernel-build-tools.
Сборка модулей на git.alt
При сборке пакета на [git.altlinux.org git.alt] необходимо указать пару (репозиторий, тэг). Для (полу)автоматического обновления модулей в Сизифе можно использовать скрипт updatemodules.
Для данного темплейта этот скрипт обновляет бранчи для указанных flavour. Например, команда
$ updatemodules -k ovz-rhel
обновит бранчи для модулей, указанных в файле kernel-image-ovz-rhel:modules.build, создаст для них подписанные тэги и положит их в файл out/taglist в рабочей директории.
dead
После этого нам нужно создать новую ветку в репозитории с модулями:
cd modules git checkout -b template/module/sisyphus origin/template/heci/sisyphus rm -f SOURCES/* mv kernel-modules-heci.spec kernel-modules-module.spec
, где module - название вашего модуля.
Теперь редактируем спек, меняем: имя, версию, описания, чейнджлог, возможно надо будет поправить опции для сборки. И коммитим.
git add *.spec git commit -a
Как выложить модуль в репозиторий
Для начала необходимо у себя в git создать репозиторий и залить kernel-source-module:
ssh git.alt init-db kernel-source-module cd kernel-source-module git remote add public git.alt:packages/kernel-source-module.git git push --all public
Потом - выложить kernel-modules
ssh git.alt clone /people/silicium/packages/kernel-modules cd kernel-build-scripts/modules git remote add public git.alt:packages/kernel-modules.git git push --all public
Осталось собрать пакеты через git.alt.
Важное замечание: для того чтобы сборка прошла правильно, kernel-source-module должен быть собран до сборки kernel-modules-module.
Рекомендации по взаимодействию с мейнтейнерами ядер
Для нормальной совместной работы рекомендуется:
- Оповестить мейнтейнеров ядер (в списке рассылки devel-kernel), о том что есть ваш модуль,
- При обновлении модуля обновлять сборки под максимальное количество ядер,
- Настроить git remote на kernel-modules других мейнтейнеров,
- В спеках kernel-modules- поле Packager установить в Kernel Maintainers team.
Про symvers и модули зависящие от других модулей
Иногда бывает, что пакет с модулями, должен собираться под другой пакет с модулями. Так например просиходит с gspca и v4l. Для нормальной сборки нам нужно 2 вещи: во-первых, проставить правильно зависимости на headers (у v4l есть свои хедеры), во-вторых, нужно импортировать файл с symvers. В gscpca проблема решилась добавлением следующей строчки в %prep фазу пакета с модулем gspca:
cat /usr/src/linux-%kversion-%flavour-%krelease/kernel-modules-v4l.symvers > Module.symvers