Parmi la myriade d'améliorations apportées au noyau Linux dans la série 2.6,
une nouvelle infrastructure nommée « kbuild » a été développée afin
de fournir un système de compilation hautement configurable et versatile. La
portée de ce changement ne sera pas étudiée dans le présent document ;
nous nous intéresserons plutôt à la nouvelle méthode recommandée pour la
compilation de modules externes contre l'arbre des sources d'un noyau 2.6.
Voici une traduction libre d'un extrait de
Compiler des modules hors du noyau officiel ------------------------------------------- Des modules sont fréquemment développés hors du noyau officiel. Afin d'être à jour relativement aux changements apportés au système de compilation, la manière la plus transposable d'un système à un autre pour compiler un module hors du noyau est d'utiliser la commande suivante : make -C chemin/vers/noyau/src SUBDIRS=$PWD modules
En écrasant la variable SUBDIRS, la plus récente architecture kbuild permet de
compiler aisément des modules externes. En soit, il s'agit d'une amélioration
Ayant configuré et compilé un noyau de la série 2.6 dont les sources résident
dans
Les modules compilés par le système Portage ont exactement le même problème : lorsqu'une mise à jour est lancée, elle échoue à cause de violations de l'environnement bac à sable. Le système kbuild a complexifié la compilation de modules de telle manière qu'il est difficile d'utiliser le principe sécuritaire des privilèges minimum.
Une recherche sur le système Bugzilla de Gentoo montre que beaucoup de bogues
causés par ce problème ont été rapportés. Aussi, beaucoup d'articles présentant
la désactivation du bac à sable comme seule solution ont été postés dans les
forums. Considérant l'état des choses à ce moment, il semblait en effet
inévitable d'avoir à écrire ou à mettre à jour des fichiers dans
Plusieurs façons de « hacker » le système kbuild afin de le
contourner ont été proposées, dont une suggérant de lier symboliquement les
éléments de
Comme il s'agit d'un risque de sécurité majeur, les utilisateurs sont forcés d'accepter cette option lors de sa première utilisation, par le bias d'un nouvel outil : config-kernel. Les utilisateurs peuvent exécuter config-kernel une fois pour accepter l'option, puis ils ne recevront qu'un avertissement chaque fois que Portage compilera un module du noyau en utilisant cette fonctionnalité.
# config-kernel --allow-writable yes
Une solution plus appropriée a vu le jour lorsqu'il est devenu évident que lutter contre les nouvelles fonctionnalités de kbuild ne causerait que des problèmes de plus en plus nombreux dans le futur. En fait, la solution réside dans la nouvelle capacité de kbuild d'envoyer tous ses fichiers de sortie dans un répertoire séparé. Garder l'arbre des sources complètement propre et permettre aux modules externes de compiler contre des sources propres tout en envoyant leurs fichiers de sortie dans un répertoire temporaire est la clé.
Les détails des interactions de tous ces éléments sont plutôt complexes. La section suivante essaie de faciliter l'assimilation de ces concepts en les décomposant en morceaux plus simples.
kbuild fournit deux variables dictant où le noyau devrait placer ses fichiers de sortie.
Variable | Utilisation |
---|---|
La combinaison de ces deux variables est la clé pour une utilisation adéquate de kbuild et Portage pour installer des modules du noyau.
Pour utiliser les fonctionnalités de redirection de la sortie du noyau, le
nouveau
Une fois que cette variable est paramétrée, toutes les commandes make exécutées dans l'arbre des sources du noyau envoyent leurs fichiers de sortie dans ce nouveau répertoire. Rien de plus n'est nécessaire de la part de l'utilisateur et le changement est essentiellement (voyez la section suivante pour les exceptions) transparent. Une fois un noyau installé, l'utilisateur n'a qu'à faire :
# make menuconfig
et ils pourront configurer leur noyau puis le compiler.
Comme tous les fichiers générés sont maintenant placés dans un répertoire
séparé, quelques fichiers clés aboutiront dans un endroit inattendu pour
l'usager. Plus particulièrement, les
Maintenant que les noyaux génèrent leurs fichiers dans un emplacement
différent, écrire des ebuilds adhérant à ce nouveau système est l'étape
suivante. Mettre à jour les ebuilds pour qu'ils vérifient la présence de
certains fichiers et en-têtes dans l'emplacement approprié et pour qu'ils
utilisent la magie
L'idée générale est de corriger les
Des changements ont été apportés à
L'utilisation de koutput oblige les
Tous les ebuilds de modules du noyau devraient désormais utiliser
Variable | Utilisation |
---|---|
La fonction kmod_src_unpack() s'applique à déterminer comment le pilote à compiler devrait être géré. Elle supporte d'ailleurs très bien les deux méthodes de compilation pour versions 2.6. Si la nouvelle méthode employant koutput est détectée, la fonction appliquera le correctif spécifié par KMOD_KOUTPUT_PATCH si celui-ci existe. Après que kmod_src_unpack() ait été appelée, une pléthore de variables deviennent disponibles et peuvent être utilisées par après dans le ebuild.
Variable | Signification |
---|---|
La valeur de KV_OUTPUT est le facteur qui, ultimement, détermine quelle configuration de noyau a été détectée et quelle méthode de compilation sera utilisée. Voici un tableau montrant les trois différentes configurations du noyau possibles et la valeur assignée à la variable après l'appel de la fonction kmod_src_unpack().
KV_OUTPUT | Approche pour compiler les modules |
---|---|
Noyau 2.4 | |
Noyau 2.6, sortie normale | |
Noyau 2.6, sortie alternative |
Une fonction assistante est fournie par kmod.eclass pour déterminer facilement quelle configuration est utilisée. is_koutput() permet à ebuild de déterminer comment procéder à la compilation. Un ebuild typique pourrait utiliser le test suivant :
if is_koutput then # Utiliser sed pour corriger certaines choses pour l'utilisation de koutput. sed -i "s:foo:bar:" Makefile fi
La plupart des ebuilds nécessiteront un correctif pour les makefiles pour activer la sortie vers un répertoire différent, puis l'utilisation de sed si is_koutput() retourne la valeur « true ». L'ebuild donné comme exemple ci-dessous montre comment cela est géré. Pour les ebuilds nécessitant plus de travail (nvidia-kernel est l'un d'eux), il y a quelques fonctions qui peuvent être appelées pour exercer un contrôle plus fin.
Fonction | Utilisation |
---|---|
En plus de ces fonctions spéciales, kmod.eclass exporte src_unpack, src_compile, etc., qui peuvent être référencées par kmod_src_unpack, kmod_src_compile, etc.
Ce qui suit est un exemple pratique détaillant comment le paquet hostap-driver
a été modifié pour créer un ebuild tout à fait fonctionnel et compatible avec
les noyaux des séries 2.4 et 2.6. Il utilise un correctif (assez général pour
être utilisé en amont et permettre la simplification des futurs ebuilds) pour
le
Vous trouverez ci-dessous des extraits du
include $(KERNEL_PATH)/.config
La version corrigée ci-dessous permet à la variable KERNEL_OUTPUT_PATH d'être
réglée si elle ne l'est pas déjà (pour la compatibilité descendante avec 2.4)
et cherche pour le fichier
ifndef KERNEL_OUTPUT_PATH KERNEL_OUTPUT_PATH=$(KERNEL_PATH) endif include $(KERNEL_OUTPUT_PATH)/.config
Comme nous avons maintenant la variable KERNEL_OUTPUT_PATH à notre disposition,
corriger la déclaration de variable suivante impliquant le
VERFILE := $(KERNEL_PATH)/include/linux/version.h
Et la version éditée et corrigée :
VERFILE := $(KERNEL_OUTPUT_PATH)/include/linux/version.h
Finalement, notre correctif remplace la ligne qui invoque le système kbuild 2.6
afin d'incorporer l'utilisation de la variable O, paramétrant le système pour
produire les fichiers dans le sous-répertoire
Voici l'original :
$(MAKE) -C $(KERNEL_PATH) SUBDIRS=$(PWD)/driver/modules \ MODVERDIR=$(PWD)/driver/modules modules
Et voici la version éditée :
mkdir -p $(PWD)/tmp -cp $(KERNEL_OUTPUT_PATH)/.config $(PWD)/tmp $(MAKE) -C $(KERNEL_PATH) O=$(PWD)/tmp \ SUBDIRS=$(PWD)/driver/modules \ MODVERDIR=$(PWD)/driver/modules modules
Les changements apportés au ebuild sont relativement simples. La eclass kmod rend d'ailleurs les choses très faciles. Voici quelques extraits de src_unpack et quelques variables paramétrées dans le ebuild :
KMOD_SOURCES="${P}.tar.gz" KMOD_KOUTPUT_PATCH="${PN}-koutput.diff.gz" src_unpack() { # Désarchive et paramètre quelques variables. kmod_src_unpack ## Désarchive les sources pcmcia-cs si nécessaire. pcmcia_src_unpack epatch "${FILESDIR}/${P}.firmware.diff.bz2" # Si koutput est utilisé, employer sed pour ajouter le chemin approprié. if is_koutput then sed -i -e \ "s:^# KERNEL_OUTPUT_PATH=.*:KERNEL_OUTPUT_PATH=${KV_OUTPUT}:" \ ${S}/Makefile fi }
Remarquez l'utilisation des deux variables,
src_compile() { # Configurer les sources pcmcia-cs tel que nécessaire. pcmcia_configure einfo "Building hostap-driver for kernel version: ${KV}" case ${KV_MINOR} in [34]) local mydrivers use pcmcia && mydrivers="${mydrivers} pccard" use hostap-nopci || mydrivers="${mydrivers} pci" use hostap-noplx || mydrivers="${mydrivers} plx" einfo "Building the following drivers: ${mydrivers}" emake ${mydrivers} || die "make failed" ;; [56]) unset ARCH emake all || die "make failed" ;; *) eerror "Unsupported kernel version: ${KV}" die ;; esac }
La fonction src_install() de cet ebuild ne sera pas montrée ici, car elle ne
fait essentiellement qu'installer tous les modules dans