Compilation croisée d’un noyau pour Raspberry Pi

Pourquoi compiler un noyau, et pourquoi faire une compilation croisée ?

Il arrive parfois que l’on ait besoin d’ajouter le support d’un protocole, ou d’un périphérique, et il n’est pas toujours possible d’utiliser un module pour cela (besoin de ressource spécifique, …). Il n’y a d’autre choix alors que de compiler un noyau.

La compilation d’un noyau Linux est une étape qui demande une bonne quantité de ressources, notamment en temps d’exécution. Je me rappelle avoir laisser une machine compiler un noyau pendant toute une nuit lorsque j’étais étudiant.

Les processeurs ont bien changé depuis, et il est maintenant possible de compiler un noyau en quelques minutes, surtout en s’aidant des nouveaux processeurs à plusieurs cœurs.

Mais toutes nos machines n’ont pas cette puissance ; le Raspberry Pi est capable de compiler ses propres noyaux, mais cela prend un temps abominable lorsque l’on veut exécuter une série de tests par la suite. Il est frustrant d’attendre plusieurs heures que la compilation se termine, pour échouer lamentablement à un test trivial.

Alors pour accélérer cette tâche nous allons avoir recours à la compilation croisée (Cross-compilation en anglais).

Installer les bons outils

Je me sers ici d’une distribution Fedora (version 19, je pense qu’il n’y aura que très peu de variations pour une version plus récente). Je l’ai installé avec l’assistant par défaut, avec le mode « Infrastructure Server » ; il s’agit d’une configuration minimaliste, sans interface graphique ni service particulier (sauf SSH). Veillez cependant à disposer de quelques gigaoctets d’espace libre, et d’un gigaoctet de RAM.

J’installe les outils dont j’ai besoin ici : le compilateur (gcc), le gestionnaire de sources (git) et un outil sympathique pour exécuter des commandes en tâches de fond (screen).

[cce_bash]yum install -y gcc-arm-linux-gnu screen git ncurses-devel[/cce_bash]

Télécharger les sources pour Raspberry Pi

Les sources du noyau Linux destiné au Raspberry Pi sont hébergées dans un depôt Git. Il s’agit d’un gestionnaire de version, capable de fonctionner de façon décentralisée. Dans un premier temps il est nécessaire de cloner ce dépôt.

[cce_bash]
mkdir -p ~/rpikernel/
cd ~/rpikernel/
git  clone http://github.com/raspberrypi/linux.git
cd linux
[/cce_bash]

Le téléchargement des sources commence et peut prendre un long moment (~1 gigaoctet de données).

La commande [cci]git branch[/cci] vous donnera la version actuelle des sources du noyau (à cette date, 3.10). Si cette version vous satisfait, vous pouvez continuer le tutoriel ; sinon, [cci]git branch -r[/cci] vous indiquera les versions disponibles. Si la 3.12 vous intéresse, entrez alors ces commandes :

[cce_bash]git branch rpi-3.12.y origin/rpi-3.12.y
git checkout rpi-3.12.y[/cce_bash]

Une fois votre version choisie, nous pouvons passer à l’étape de la configuration de la compilation.

Générer sa configuration

Il y a trois moyens de générer la configuration de la compilation :

  • depuis zéro, en saisissant un à un les choix proposés par l’assistant [cci]make config[/cci] (non recommandé)
  • en utilisant le fichier de configuration par défaut, que l’on trouve dans arch/arm/configs/bcmrpi_defconfig dans le répertoire des sources. Il suffit de copier ce fichier à la racine, et de le renommer « .config ». On utilisera ensuite l’assistant de configuration de la compilation (voir plus loin).
  • en exploitant un fichier de configuration existant, que l’on peut extraire avec la commande [ccie]zcat /proc/config.gz > .config[/ccie] (sur un Raspberry Pi). On copie ensuite ce fichier à la racine du répertoire des sources (fichier nommé .config). C’est la façon la plus correcte lorsque l’on sait précisément ce que l’on souhaite modifier.

Pour éditer ce fichier de configuration, il est plus confortable d’utiliser l’assistant dédié :

[cce_bash]make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- menuconfig[/cce_bash]

Notez l’ajout des termes ARCH=arm (pour spécifier l’architecture cible) et CROSS_COMPILE=/usr/bin/arm-linux-gnu- (pour spécifier les outils de compilation à utiliser). Ces déclarations sont indispensables pour indiquer au compilateur que l’on est en train de compiler un noyau pour une autre architecture.

En exécutant la commande menuconfig, vous découvrirez un menu permettant de configurer votre noyau à votre guise. Libre à vous de le modifier.

Enfin, vous pouvez donner un petit nom à votre noyau, en renseignant les variables EXTRAVERSION et NAME du Makefile à la racine. EXTRAVERSION sera notamment visible à l’aide de la commande [cci]uname -r[/cci].

Lancer la compilation

Ici, il n’y a rien de plus simple :

[cce_bash]make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu-[/cce_bash]

Vous pouvez profiter même des capacités multi-coeurs de votre machine avec l’option -j pour indiquer le nombre de coeurs à utiliser

[cce_bash]make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- -j 4[/cce_bash]

Et n’oubliez pas de compiler les modules ensuite !

[cce_bash]make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- modules[/cce_bash]

Installer votre nouveau noyau

Pour ne pas trop se fatiguer, on va utiliser SSHFS pour monter le noyau fraichement compiler, et ainsi installer les modules très facilement. Installons d’abord SSHFS sur le Raspberry Pi (je suppose que vous utilisez une Raspbian, vous trouverez aisément la façon de le faire si ce n’est pas le cas) :

[cce_bash]sudo su –
aptitude install -y sshfs[/cce_bash]

Puis, toujours depuis le Raspberry Pi, montons les sources du noyau (remplacez crosscompilemachine par l’IP de votre machine qui sert pour la compilation) :

[cce_bash]mkdir -p /mnt/rpikernel
sshfs root@crosscompilemachine:~/rpikernel /mnt/rpikernel[/cce_bash]

Rendons nous maintenant dans ce répertoire et installons les modules ainsi que le noyau :

[cce_bash]cd /mnt/rpikernel/linux
make modules_install
cp arch/arm/boot/Image /boot/kernel.img
[/cce_bash]

Après un redémarrage de votre Raspberry Pi, vous devriez avoir un noyau tout neuf !

Cet article est inspiré de celui-ci, en anglais.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*