Google PlusFacebookTwitter

Linux From Scratch et ARM Cortex-A7 – Partie 2

By on Nov 27, 2013 in Embarqué, Linux | 4 comments

Share On GoogleShare On FacebookShare On Twitter

La chaîne de compilation, une étape qu’elle est cruciale !!

Première phrase et déjà une superbe faute de français… tout fout le camp !

Dans le premier billet de cette série (cf. Linux From Scratch et ARM Cortex-A7 – Partie 1),  j’ai évoqué ce qu’était une chaîne de compilation a.k.a une toolchain dans la langue de « ChaQueSpéAre ». Pour ceux qui ont la flemme de lire ou relire ce billet voici ce que vous auriez du retenir :

Une chaîne de compilation est un groupe d’outils permettant la compilation d’un programme d’une architecture processeur à une autre. En général, on y trouve les outils suivants : BinutilsCloogeGlibcGCCGMPISLNoyau LinuxMPCMPFR. Ces librairies sont nécessaires à la compilation de GCC (cf. http://gcc.gnu.org/install/prerequisites.html).

Toujours dans mon précédent billet, j’ai évoqué plusieurs possibilités pour la mise en place de cette chaîne de compilation. Je les cite brièvement :

  1. Compiler les librairies une à une pour ensuite compiler GCC
  2. Utiliser un outil permettant de générer automatiquement une chaîne de compilation
  3. Passer par le gestionnaire de paquets de votre distribution

J’ai choisi la seconde méthode qui est à mon sens la meilleure des trois, elle mélange apprentissage, automatisation et optimisation.

Parce qu’il n’y a pas d’âge pour l’apprentissage !

Linux From Scratch est pour ma part une envie d’apprendre, de savoir comment fonctionne le système que j’utilise au quotidien et qui me permet de payer mon loyer. Comme tout administrateur système, le compilateur GCC ça me parle. Mais quid des librairies GMP, MPC, Cloog, etc… ? Que nenni !

La compilation croisée (cross-compilation, x-compile, ect…) n’avait aucun intérêt pour moi jusqu’à l’acquisition de mon Raspberry Pi et plus récemment de mon A20 OLinuXino. Une fois le nez dedans, c’est comme commencer une recherche sur Wikipédia. On commence par une recherche banale puis on clique sur un autre article et ainsi de suite, pour au final passer la moitié de la nuit à apprendre de nouvelles choses.

Et bien, il en est de même pour la compilation croisée, le sujet est vague ! Soyez patient, le chemin vers la compilation croisée est semé d’embûches (ceci n’est pas tiré d’un biscuit chinois).

Que l’automatisation soit…

Un peu d’automatisation dans ce monde de compilation. Plusieurs projets liés au déploiement d’une chaîne de compilation existent, j’en citerai deux pour vous laisser une petite porte de secours.

Mon boucher a tranché, c’est Crosstool-NG (cf. http://www.ina.fr/video/PUB160516131).

Cette solution est la plus adaptée dans notre cas. Loin de moi l’idée de dénigrer BuildRoot, j’expose simplement le fait que ce dernier peut être trop complet par rapport à nos attentes. Il nous proposera par exemple de compiler un noyau, busybox, etc… cela ne nous intéresse aucunement pour le moment.

Crosstool-NG, un script shell bien couillu ! Une interface développée en Ncurses vous rappellera des souvenirs de compilations de noyau Linux, des nuits passées à essayer de compiler un module de carte son ou encore le fameux pilote fglrx… Crosstool-NG dernier propose d’utiliser des options dites « expérimentales », il ne faut pas avoir peur de ce terme.

Interface Crosstool-NG

Un petit truc que j’ai trouvé sympa, est la possibilité d’utiliser le compilateur GCC Linaro. Je vous vois venir : « Mais c’est quoi Linaro ? » :

Linaro est tout le contraire d’un énième groupement d’industriels ne produisant que des spécifications à usage interne. Son unique vocation est de développer de nouvelles fonctionnalités tirant partie des processeurs ARM les plus récents, et de faire intégrer ces contributions dans les versions officielles de la communauté (noyau Linux, compilateurs, QEMU…). Linaro a un fonctionnement complètement ouvert, et n’importe quelle bonne volonté peut participer à ses projets et à ses discussions techniques.

Certaines personnes constatent un gain de performance allant jusqu’à 50% en fonction des domaines d’utilisation. Je pense que ces propos sont à prendre avec des pincettes, libre à vous d’effectuer quelques comparatifs et de les partager !

La meilleure partie, l’optimisation

Ce qui suit est la meilleure partie, elle consiste à optimiser la chaîne de compilation en fonction du processeur cible à savoir un ARM Cortex-A7. Les optimisations à apporter à Crosstool-NG sont les suivantes (attention, merci de noter que je n’ai pas la science infuse).

La version 4.8.2 de GCC supporte très bien le processeur ARM Cortex-A7, une liste des options supportées par GCC est disponible ici : http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html

Comme toutes les bonnes choses, il ne faut pas abuser des options d’optimisation. Compiler GCC avec un niveau d’optimisation trop élevé peut avoir des conséquences sur les performances d’un programme. C’est pour cela que je vous invite à utiliser le niveau 2 (-O2) d’optimisation au lieu du niveau 3 (-O3) sauf si vous savez ce que vous faites.

Let’s do it \o/

Passons à l’installation de Crosstool-NG, c’est la partie la plus simple. Il suffit de télécharger les sources puis de les compiler, vous voyez, rien de compliqué !

Pré-requis :

Crosstool-NG est installé ! Le PATH de l’utilisateur ayant été mis à jour, la commande ct-ng fait donc son apparition dans votre liste de commandes disponibles.
ct-ng permet de sélectionner les options de la chaîne de compilation puis de compiler cette dernière.

Un petit test de routine :

Résultat :

Dans les commandes ci-dessus, il y a un wget qui récupère le fichier de configuration config-cortexa7, ce fichier contient toutes les options nécessaires pour un processeur ARM Cortex-A7. Encore une fois, cette configuration est tirée de mon expérience, il est donc possible que le fichier mis à disposition ne soit pas parfait, libre à vous de le modifier et de partager vos modifications. 😉

Quoiqu’il en soit, avant de lancer la compilation, je vous invite à exécuter la commande ct-ng menuconfig afin de parcourir l’interface en Ncurses (voir la capture un peu plus haut) et d’avoir une idée des options disponibles.

La compilation de la toolchain est assez longue, dans mon cas le temps de compilation fut d’environ 50 minutes sur un Core I5. La compilation se fait via la commande ct-ng.

Patience… Pour faire passer le temps, je vous invite à regarder un épisode de South Park et plus particulièrement « La meilleure gagneuse de Butters » (si vous êtes un vrai :mrgreen: ).

Le moment de vérité

Une fois la compilation terminée, il ne reste plus qu’à tester le bon fonctionnement des nouveaux outils. C’est simple, le premier test consiste à lancer GCC en mode « version » et de voir ce qu’il retourne. Le second test consiste à compiler un petit hello world et de vérifier que l’architecture cible est bien celle que nous souhaitons.

Premier test

Résultat :

Second test

Compilation du code ci-dessus avec le compilateur GCC fraîchement installé.

Vérification de l’architecture cible :

Résultat :

Et d’un point de vue ELF ?

Résultat :

Tout semble être à sa place, le binaire hello est maintenant exécutable sur une plate-forme dotée d’un processeur ARM Cortex-A7 !

Conclusion

Pfiou ! Ce fut long, long, très long billet… J’espère que cette seconde partie aura été à votre goût et que votre mépris envers moi reste minime.
Le prochain billet aura pour sujet la mise en place d’un gestionnaire de démarrage U-Boot sur une carte A20 OLinuXino.

Liens

The following two tabs change content below.

Gaëtan Trellu (goldyfruit)

Cloud Operations Lead chez Ormuco
Autodidacte en informatique, depuis 2005 je parcours l’écosystème Unix à la recherche de nouvelles connaissances et de nouvelles rencontres.

CC BY 4.0 Linux From Scratch et ARM Cortex-A7 – Partie 2 par Gaëtan Trellu (goldyfruit) est sous Licence Creative Commons Internationale Attribution 4.0.