Packager son noyau
Par Jérôme Pouiller le samedi, mai 16 2009, 18:21 - Technique - Lien permanent
Lorsque l'on touche au noyau, on se trouve rapidement confronté au problème de la distribution du noyau et de ses modules additionnels.
Je propose d'expliquer comment j'ai empaqueté le noyau 2.6.28.9 pour la société Substantiel. Il s'agit d'un cas complet avec des patch et des modules externes.
Récupération et patch du noyau
On commence par récupérer un noyau tout neuf:
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.9.tar.bz2 tar xvjf linux-2.6.28.9.tar.bz2
On applique nos patchs:
cd linux-2.6.28.9 patch -p1 < ../bootsplash-3.1.6-2.6.28.9.patch patch -p1 < ../logitechE2500-2.6.28.9.patch patch -p1 < ../uvc-ctrl-blacklist-2.6.28.9.patch patch -p1 < ../substantiel-modules.patch
Le patch substantiel-modules.patch
permet d'intégrer un nouveau sous-répertoire dans le noyau. J'y reviendrais.
Remarquez qu'il existe dans make-kpkg
des options spéciales pour gérer les patchs. C'est un mauvaise idée de les utiliser. Elles sont boguées et seront bientôt obsolètes. Ça n'est pas moi qui le dit, c'est dans la documentation de make-kpkg
.
Choix des sources des modules externes
Il y a deux stratégies:
- Les modules que l'on peut trouver chez Ubunu sont patchés de manière à compiler DANS l'arborescence du noyau. Cette stratégie demande généralement de beaucoup pachter les sources originales.
- Les modules fournis par Debian sont moins patchés. Il ne compilent pas forcement de manière très catholique, mais sont empaquetés de manière à être compatible avec make-kpkg, que nous utiliserons par la suite.
On peut voir la différence entre les deux méthodes sur le fichier conftest.h
du driver nvidia. Il a été entièrement réécrit pour Ubuntu et c'est beaucoup mieux (exemple: http://www.mail-archive.com/debian-...)
Dans mon cas, j'ai utiliser un modèle hybride. J'ai majoritairement repris les sources de Debian, mais je n'ai pas hésité à ajouter des modules directement dans l'arborescence du noyau lorsque c'était plus évident.
Intégration des modules externes
Récupération des modules
On récupère les modules de Debian:
apt-get source -t unstable ndiswrapper-utils nvidia-glx fglrx-glx rt2860-source
Le module Microdia n'était pas empaqueté. J'ai préféré le mettre dans un paquet séparé. J'ai donc procédé à la Debianisation de ce module (qui était triviale):
wget http://repo.or.cz/w/microdia.git?a=snapshot;h=4f79407ff1a6db30aba7c0d80a67f634fae5e19b;sf=tgz
Empaquetage des modules externes
On s'apprête à créer des paquets Debian, donc mettons en place certaines variables d'environnement:
export NAME="Jérôme Pouiller" export EMAIL=jezz@sysmic.org export GNUPGHOME=/home/jezz/.gnupg # export DEB_BUILD_OPTIONS='parallel=5' # Pose problème avec make-kpkg, nous en reparlerons
Mettre à jour les changelog
Procédure classique pour mettre à jour des paquets Debian:
for i in nvidia-graphics-drivers-180-180.44 ndiswrapper-1.54 fglrx-driver-9.3 rt2860-source_1.8.0.0-3 microdia-090504 pushd $i && dch --local substantiel --force-distribution --distribution ordissimo Port to Ordissimo && popd
Compiler les parties userland
Procédure classique pour construire des paquets Debian:
for i in nvidia-graphics-drivers-180-180.44 ndiswrapper-1.54 fglrx-installer-9.3 rt2860-source_1.8.0.0-3 microdia-090504 pushd $i && debuild && popd
Décompresser les sources des modules
dpkg -X nvidia-kernel-source_180.44-2s1_i386.deb nvidia-kernel-source_180.44-2s1 tar xvjf nvidia-180-kernel-source_180.44-0ubuntu1s1/usr/src/nvidia-kernel.tar.bz2 ln -s nvidia-kernel modules/nvidia-180.44 dpkg -X fglrx-source_9-3-1s1_i386.deb fglrx-source_9-3-1s1 tar xvjf fglrx-source_9-3-1s1/usr/src/fglrx.tar.bz2 ln -s fglrx modules/fglrx-9.3 dpkg -X ndiswrapper-source_1.54-2s1_all.deb ndiswrapper-source_1.54-2s1 tar xvjf ndiswrapper-source_1.54-2s1/usr/src/ndiswrapper.tar.bz2 ln -s ndiswrapper modules/ndiswrapper-1.54 dpkg -X rt2860-source_1.8.0.0-3s1_all.deb rt2860-source_1.8.0.0-3s1 tar xvjf rt2860-source_1.8.0.0-3s1/usr/src/rt2860.tar.bz2 ln -s ../rt2860-source_1.8.0.0-3s1/usr/src/modules/rt2860 modules/rt2860-1.8.0.0 dpkg -X fglrx-source_9-3-1s1_i386.deb fglrx-source_9-3-1s1 tar xvjf fglrx-source_9-3-1s1/usr/src/fglrx.tar.bz2 ln -s fglrx modules/fglrx-9.3 dpkg -X microdia-source_090504-s1_all.deb microdia-source_090504-s1 tar xvjf microdia-source_090504-s1/usr/src/microdia.tar.bz2 ln -s microdia modules/microdia-090504
Les sources de nos modules sont prête à être empaquetée avec make-kpkg
.
Intégration des modules dans l'arborescence du noyau
On créé ensuite le sous-répertoire substantiel
dans l'arborescence du noyau. On ajoute ce répertoire à la variable drivers-y
dans le Makefile racine:
drivers-y := drivers/ sound/ firmware/ substantiel/
Dans le fichier arch/x86/Kconfig
, on inclut le nouveau sous-répertoire:
source "substantiel/Kconfig"
Ensuite, on ajoute nos modules:
cd substantiel svn checkout http://svn.madwifi-project.org/madwifi/trunk madwifi-20090424 wget http://www.broadcom.com/docs/linux_sta/hybrid-portsrc-x86_32-v5_10_79_10.tar.gz wget http://msi-wind-linux.googlecode.com/files/rtl8187se_linux-04.tar.bz2 ln -s hybrid-portsrc-x86_32-v5_10_79_10 broadcom ln -s madwifi-20090424 madwifi ln -s rtl8187se_linux-04 rtl8187se-04
Si nous avions voulu mettre ces modules dans des paquets séparés du noyau, il aurait fallu utiliser dh_make --kmod
pour les empaqueter.
Configuration
Récupérons notre ancienne configuration et mettons la à jour:
cp config-2.6.28.7-ordissimo linux-2.6.28.9/.config make -C linux-2.6.28.9 oldconfig diff -U 0 config-2.6.28.7-ordissimo linux-2.6.28.9/.config > config-2.6.28.7-2.6.28.9.diff
Empaquetage
make-kpkg
Nous allons utiliser make-kpkg pour empaqueter. Ne vous arrêtez pas à ce choix. Il existe d'autre scripts d'aide au packaging du noyau. D'ailleurs Debian ne utilise plus make-kpkg
pour ses noyaux officiels et Ubuntu ne l'a jamais utilisé.
De plus, make-kpkg a subit de grosse modification à partir de la version 12. Dans notre cas, il est important d'utiliser une version antérieure à 12. Pour connaitre les modifications apportées, référez-vous au fichier NEWS.Debian de kernel-package 12.
Certaines personnes disent que make-kernel est complètement obsolète (il a été créé pour noyau 2.0) et que la documentation ne vaut plus grande chose avec le noyau 2.6. Je suis de ceux-là. J'ajoute de plus que :
kernel-package
est mal documenté (par exemple,$CLEAN_SOURCE
n'est pas indiquée comme modifiant le comportement demake-kpkg
dans la page de manmake-kpkg(1)
).- Il faut souvent regarder le code pour comprendre ce qu'il se passe.
- Des choses comme:
... make[2]: warning: -jN forced in submake: disabling jobserver mode. ====== making target debian/stamp/install/linux-source-2.6.28.9 [new prereqs: ]====== make[1]: *** [debian/stamp/do-install-indep] Segmentation fault ...
Ne devrait jamais arriver$$Il s'agit ici d'un problème avec la parallélisation de make. C'est pour cette raison que DEB_BUILD_OPTIONS='parallel=5'
était commenté précédemment.
- L'imbrication des Makefile rend make-kpkg très lent à l'exécution
- Il est d'une complexité qui n'est plus nécessaire avec KBuild.
- Il n'est pas très compatible avec les normes existantes pour Debian (variables
$EMAIL
,$NAME
, création de l'archive source, etc...).
En comparaison, les systèmes de création de paquets noyau de Debian et Ubuntu sont beaucoup plus simples. Bref, je garde kernel-package uniquement parce que c'est la méthode ancestrale mais il serait temps de se mettre à jour. Notons néanmoins qu'il n'existe à l'heure actuelle aucun système d'empaquetage du noyau répondant à tous les problèmes existants.
Empaquetons
Définission quelques variables d'environnement utile:
export MODULE_LOC=$(pwd)/../modules # Ces variables sont utilisées dans les modules externes. Dans un monde parfait, elle ne devraient pas exister export MAKEFLAGS="SYSSRC=$(pwd) KERNPATH=$(pwd) KERNELPATH=$(pwd) KBUILD=$(pwd)" # Pour compiler plus vite export CONCURRENCY_LEVEL=5 # Pour ne pas oublier --revision s1 export DEBIAN_REVISION_MANDATORY=1 # Pour ne pas oublier --initrd export INITRD=1 # S'il te plait, ne flingue pas tout mon boulot à la fin de la compilation export CLEAN_SOURCE=no # Je ne veux pas être root export ROOT_CMD=fakeroot # On utilisera cette fonctionnalité une prochaine fois #PATCH_THE_KERNEL=AUTO #ALL_PATCH_DIR=$(pwd)/../patch # Il y a pleins de problèmes avec option "parallel=X" unset DEB_BUILD_OPTIONS
J'ai vu tellement de problèmes avec make-kpkg
que je préconise de lancer les cibles une par une:
MAKE_CMD="fakeroot make-kpkg --rootcmd fakeroot --revision s3 --added_modules ndiswrapper-1.54,nvidia-180.44,fglrx-9.3,microdia-090504,rt2860-1.8.0.0 --config menuconfig --initrd" $MAKE_CMD configure $MAKE_CMD binary-arch $MAKE_CMD modules $MAKE_CMD binary-indep # Finish ! $MAKE_CMD buildpackage
En cas de modification de la configuration
Si vous faite une modification dans la configuration du noyau et que vous ne souhaitez pas tout recompiler, supprimez simplement le répertoire debian/stamp
(ou même tout le répertoire debian
, il sera recréé).