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 de make-kpkg dans la page de man make-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éé).