Un site codé avec du
vrai Javascript, du PHP8,
de l'HTML5 et du CSS3 !

Les astuces de TPXP

Un blog sur tous les petits problèmes que j'ai pu rencontrer devant mon PC ou ailleurs. On ne sait jamais, ça peut servir...

Les joies de l'ARM : qu'y a-t-il dans nos ordiphones ?

Un article pour comprendre la différence entre un ordiphone et un ordinateur plus classique, et ce que ça implique!

Ma petite histoire avec le merveilleux monde de l'ARM commence il y a environ un an, lorsque j'ai voulu m'équiper d'un micro-ordinateur pour faire un petit serveur web, afin de soulager un peu mon ordinateur et d'avoir quelque chose de disponible à toute heure (au passage, c'est lui qui héberge ce blog!). J'aurais pu faire comme tout le monde: acheter une Raspberry Pi, mais mon choix s'est plutôt tourné vers un autre système, un peu plus performant: une Odroid-XU, vendue par le fabriquant sud-coréen HardKernel. Après une facture de douane assez salée (une bonne cinquantaine d'euros avec les frais de dossiers, sur un appareil à 130€ ça commençait à faire cher), le boitier a finalement atterri dans mes mains, super!

Utiliser un micro-ordinateur ARM, en soi, ça n'a rien de bien compliqué : branché au réseau, avec Linux installé sur sa carte microSD, mon petit système fonctionnait très bien. La difficulté est venue quand j'ai voulu en faire un lecteur multimédia, pour le brancher à la télévision et afficher les films et photos de famille...

Comment j'ai rien compris à l'ARM

Pour remplir ce rôle, il existe un logiciel très populaire, réalisant très bien le travail et répondant au doux nom de Kodi (anciennement XBMC). Étant équipé de Linux (ArchLinuxARM, en l’occurrence) sur mon boîtier, j'ai voulu l'installer, comme n'importe qui aurait fait, avec le gestionnaire de paquets par défaut.

  1. # pacman -S kodi

L'installation c'est passée sans trop de soucis. Mais la loi de Murphy ne pouvait pas m'épargner lorsqu'il a fallu lancer tout ça :

  1. $ kodi
  2. Error: unable to open display
  3. Kodi needs hardware accelerated OpenGL rendering.
  4. Install an appropriate graphics driver.

Assez décevant, tout de même... Quelques recherches m'orientaient vers un pilote spécial afin de créer un environnement graphique. Une fois cette interface graphique fonctionnelle, j'ai essayé de lancer Kodi (comme on fait sur un ordinateur de bureau, en fait). Celui-ci a cette fois-ci accepté de démarrer, en utilisant l'environnement graphique disponible. Mais malheureusement l'interface était inutilisable : elle était terriblement lente !

Le forum officiel du fabriquant présente quelques installations prêtes à l'emploi, qui sont elles parfaitement fluides. Quel était donc le secret de leurs concepteurs, pour arriver à une telle fluidité ?

Pour percer ce mystère, il n'y a pas de secret : il faut savoir de quoi l'on parle, et comprendre comment ça marche!

De quoi parle-t-on ?

Afin de comprendre ce qu'est l'ARM, et en quoi un micro-ordinateur est différent d'un ordinateur classique, un point s'impose sur le composant central de tout ordinateur : le processeur !

Le processeur est un composant électronique se présentant sous la forme d'un parallélépipède rectangle à base carrée de quelques millimètres de hauteur, ressemblant à peu près à ceci (merci à Bill Ebbesen pour la photo):

Illustration

Ce composant se fixe sur la carte mère de l'ordinateur (c'est le support sur lequel se branchent tous les composants : la mémoire vive (dont nous avons parlée dans l'article sur les chaînes), les disques durs, les différentes cartes pour le son et la vidéo, et j'en passe!

Une fois installé sur la carte mère, avec son ventilateur (ça chauffe, mine de rien!), ce composant traite les différentes instructions qu'il reçoit de la part du système d'exploitation (gestion de la mémoire vive, envoi d'une information à un composant spécifique, ...). Comment me direz-vous ?

Un processeur, comment ça marche ?

Pour communiquer avec les autres composants de l'ordinateur, le processeur utilise la carte mère. Et il communique avec elle à l'aide de nombreux connecteurs, comme on peut le voir sur l'autre face du processeur (merci à Bill Ebbesen pour la photo):

Illustration

Vous voyez toutes ces petites zones en or ? Sur la carte mère, il y a des connections au même endroit, ce qui permet au processeur de communiquer avec la carte mère pour accomplir au mieux sa mission!

Comme vous pouvez l'imaginer, certaines zones sont utilisés pour envoyer des ordres au processeur (on parle d'entrées), et d'autres sont utilisées par le processeur pour envoyer des ordres (on parle de sorties). Le processeur n'est donc rien d'autre qu'un composant électronique avec des entrées et des sorties.

Comme vous pouvez vous en douter, les entrées sont dépendantes de sorties, et ce de manière assez directe. On peut donc exprimer chaque sortie en fonction des entrées.

Petit cours de logique

Pour ce faire, on utilise ce que l'on appelle des équations logiques. Pour résumer, il s'agit d'équations dans lesquelles on donne à chaque entrée et sortie une lettre, puis que l'on relie à l'aide d'opérateurs. Chaque lettre n'a que deux valeurs : Vrai (1) ou Faux (0). Les opérateurs fondamentaux sont :

● l'opérateur égal "=" : il permet d'indiquer une égalité entre deux expressions. Par exemple, si la sortie C a la même valeur que A, on écrira : C = A.

● l'opérateur et "." : il retourne Vrai si les deux lettres qu'il relie ont la valeur Vrai. Sinon, il retourne Faux. Par exemple, si la sortie C n'est vraie que si A et B sont vraies, on écrira : C = A.B).

● l'opérateur ou "+" : il retourne Vrai si au moins une des deux lettres qu'il relie a la valeur Vrai. Ainsi, si on l'on veut que la sortie C soit vraie si A ou B est Vraie, on écrira : C = A+B).

● l'opérateur non "┐" (aussi noté par une barre au dessus de l'expression) : il permet de prendre l'opposé de l'expression. Par exemple, si l'on veut que C ait la valeur opposée à celle de A, on écrira : C=┐A

Ces opérateurs peuvent décrire tous les comportements possibles. Pas convaincu ? Voyons un exemple. Prenons les sorties C et D, dépendantes des entrées A et B selon le tableau suivant (que l'on nomme table de vérité; ici c'est celle d'un additionneur binaire) :

  1. ┌─┬─╥─┬─┐
  2. │A│B║C│D│
  3. ├─┼─╫─┼─┤
  4. 0000
  5. ├─┼─╫─┼─┤
  6. 0101
  7. ├─┼─╫─┼─┤
  8. 1001
  9. ├─┼─╫─┼─┤
  10. 1110
  11. └─┴─╨─┴─┘

On peut écrire les équations logiques suivantes :

C = A.B

D = A.(┐B) + B.(┐A)

Dans un processeur, toutes les sorties ont des équations logiques similaires (même si elles sont bien plus compliquées que ça, en raison du nombre d'entrées !). Elles ne font pas intervenir plus d'opérateurs que ceux présentés ci-dessus (parfois, on utilise un symbole pour raccourcir l'expression, mais au final on peut se ramener à ceux que je vous ai présentés ci-dessus).

Petit cours d'électronique

Dans un circuit électronique (celui d'un ordinateur par exemple), les états logiques des variables sont représentées par un potentiel électrique sur un fil électrique (correspondant à la variable logique). Pour simplifier, nous prendrons ici un potentiel de 5V lorsque la variable est vraie, et un potentiel de 0V lorsque celle-ci est fausse.

Comme vous vous en doutez déjà, il n'y a pas de magie dans ce petit composant qu'est le processeur. Aussi, pour gérer les variables logiques en changeant leur potentiel électrique, on a recours à un composant essentiel en électronique : le transistor (ici, nous l'étudierons en régime saturé, mais il est possible de l'utiliser différemment).

Ce composant comporte 3 bornes, et fonctionne un peu comme un interrupteur, mais commandé par l'électricité : lorsque un courant arrive sur la branches nommée collecteur, le contact est établi entre les deux autres bornes (la base et l'émetteur), ce qui permet au courant de passer selon un certain sens (de la base à l'émetteur). Dans le cas contraire, les deux branches ne sont pas en contact, et le courant ne passe pas. Sur les circuits électroniques grandeur nature, un transistor ressemble à ceci :

Illustration

Le transistor est représenté sur les schémas électriques par ce symbole (parfois sans le rond autour) :

Illustration

Ces transistors sont assemblés afin que le potentiel de sortie soit le bon par rapport aux entrées en fonction de l'équation logique. Il est en effet possible, à l'aide d'un transistor, de reproduire le comportement de tous les opérateurs en logique, et en particulier le "et" et le "non". Voyez plutôt cet exemple de circuit pour réaliser l'opérateur "non" :

Illustration

Le variable logique est ici représentée par l'entrée en bleu, surmontée de la lettre A. Et la sortie est représentée par la lampe, surmontée de la lettre S. La variable logique fournit ou non un courant au transistor, qui est alors passant ou non. Lorsque la variable logique d'entrée est vraie, le transistor est passant car il reçoit du courant sur sont collecteur. La lampe est alors court-circuitée : la différence de potentiel à ses bornes est nulle, et la sortie est donc fausse.

Illustration

Dans le cas contraire (si notre variable logique d'entrée est fausse), le transistor ne reçoit pas de courant sur son collecteur, et est donc bloquant. L'intensité dans le circuit principal (celui avec la lampe) est alors quasi-nulle (I ≈ 0 A), la différence de potentiel aux bornes de la résistance est alors quasi-nulle (d'après la loi d'Ohm U = R × I), ce qui nous donne une différence de potentiel aux bornes de la lampe de 5V environ (d'après la loi des mailles). La sortie est donc vraie.

Illustration

Comme vous l'avez remarqué, lorsque la variable logique est vraie, la sortie S est fausse, et inversement : on a bien créé une porte logique "non", qui respecte l'équation logique S=┐A.

La porte logique "et" est quant à elle tout ce qu'il y a de plus simple :

Illustration

Le courant ne peut passer que si les deux transistors sont passants, ce qui implique que les deux variables logiques A et B soient vraies. On a alors une différence de potentiel aux bornes de la lampe de 5V : la sortie est vraie. Si l'une des deux variables est fausse, le courant ne passe pas (I ≈ 0 A), et la différence de potentiel aux bornes de la résistance est donc nulle (d'après la loi d'Ohm U = R × I). Il en est de même aux bornes de la lampe, et la sortie est donc fausse.

On a bien ici une porte logique respectant l'équation logique S = A.B

Retour à la logique

Maintenant que nous savons implémenter deux portes, il est temps pour nous de montrer qu'elles sont suffisantes pour recréer tous les opérateurs élémentaires de logique.

Pour ce faire, nous allons utiliser ces deux égalités :

● L'opposé de l'opposé d'une variable est cette variable ┐(┐A) = A. Plutôt évidente comme équation, étant donné que nous n'avons que deux états logiques, si l'on prend deux fois l'autre, on retombera forcément sur l'état initial !

● Le théorème de De Morgan (┐A).(┐B) = ┐(A + B). Ce théorème est un peu moins évident, mais il est tout aussi vrai. Prenez une feuille, et faites une table de vérité des deux côtés de l'équation en fonction de A et B, vous devriez obtenir ceci, en notant C et D les deux côtés de l'équation:

  1. ┌─┬─╥─┬─┐
  2. │A│B║C│D│
  3. ├─┼─╫─┼─┤
  4. 0011
  5. ├─┼─╫─┼─┤
  6. 0100
  7. ├─┼─╫─┼─┤
  8. 1000
  9. ├─┼─╫─┼─┤
  10. 1100
  11. └─┴─╨─┴─┘

Nous avons déjà les circuits des portes logiques "non" et "et", aussi il ne nous manque que celui de la porte "ou" pour avoir tous les opérateurs élémentaires. Nous n'allons pas le faire, mais exprimer le "ou" en fonction des opérateurs "et" et "non", pour faire un petit exercice...

Commençons par utiliser la formule du double opposé...

A + B = ┐(┐(A + B))

Utilisons ensuite le théorème de De Morgan:

┐(┐(A + B)) = ┐((┐A).(┐B))

C'est tout ! Nous venons d'exprimer l'opérateur "ou" en fonction des opérateurs "non" et "et" !

A + B = ┐((┐A).(┐B))

Voilà qui montre que tous les opérateurs logiques peuvent être réalisés avec des transistors.

Qu'y a-t-il dans un processeur ?

Comme je vous le disais, un processeur a pour seul rôle de gérer les sorties en fonction des entrées, en obéissant toujours aux mêmes équations logiques. Or, nous venons de voir que les équations logiques pouvaient être implantées matériellement avec des transistors, et c'est la solution qui a été retenue dans les processeurs de nos ordinateurs. Et oui, dans cette petite puce, si importante, il n'y a rien d'autres que des millions de transistors assemblés pour que les sorties soient gérées correctement en fonction des entrées. Bien entendu, ces transistors ne font pas la taille de celui que je vous ai montré plus haut, ils sont bien plus petits : les processeurs sont fabriqués en gravant les composants internes du transistor (notamment du Silicium) sur une plaque, avec un précision extrême : certains processeurs sont gravés avec une précision de l'ordre de la dizaine de nanomètres (1/1 000 000 000 m !). C'est bien nécessaire pour faire rentrer tout ce petit monde là-dedans!

Communiquer avec un processeur

Pour communiquer avec le reste des composants de l'ordinateur, le processeur doit avant tout savoir que faire ! Et, pour lui donner des ordres, il faut lui parler dans sa langue (à l'aide des entrées logiques).

D'une manière générale, on parle toujours au processeur en utilisant un langage (ou jeu d'instructions) répondant au doux nom d'Assembleur. Mais il y a des variantes !

Une affaire d'architecture

Au début, quand les capacités en mémoire étaient encore assez limitées, on a préféré travailler sur 32 bits, c'est-à-dire en écrivant les nombres à l'aide de 32 bits (un bit étant un chiffre valant 0 ou 1). C'était l'architecture 32 bits, qui a succédé aux précédentes et c'est imposée pendant de nombreuses années. Pour parler à un processeur de l'architecture 32 bits, on utilise l'Assembleur x86.

Mais, les capacités de mémoire augmentant, les processeurs 32 bits ont commencé à montrer leurs limites, aussi on a inventé l'architecture 64 bits, pour gérer plus de mémoire et des nombres plus grands (étant donné qu'on pouvait se permettre d'écrire des nombres sur plus de bits). Les processeurs 64 bits sont toutefois restés compatibles avec les instructions prévues pour les processeurs 32 bits. Leur langage est donc une extension de l'Assembleur x86 (il y a des commandes en plus, pour aller plus vite). C'est pourquoi on a donné le nom d'Assembleur x86_64 au langage des processeurs utilisant l'architecture 64 bits.

De la compilation

Alors, où retrouve-t-on cet Assembleur, me direz-vous ? Il est vrai que, désormais, plus personne n'écrit de programme en Assembleur : on a recours à un autre langage (comme le C) qui est ensuite compilé, c'est-à-dire transformé en Assembleur, à l'aide d'un programme nommé compilateur.

Si un programme est compilé en Assembleur x86, il pourra être exécuté sur les processeurs 64 et 32 bits, étant donné que l'Assembleur x86_64 est compatible avec l'Assembleur x86. Mais, si l'on compile un programme en Assembleur x86_64, alors on pourra avoir recours à des fonctions absentes de l'Assembleur x86 : le programme ne pourra pas être exécuté sur un processeur 32 bits, mais uniquement sur un processeur 64 bits.

Vous l'aurez compris, les architectures de processeurs utilisés dans nos ordinateur supportent des langages assez proches. Mais, pour ce qui est de l'ARM, c'est une autre histoire !

Différences notables de l'architecture ARM

Avant de nous plonger dans les différences entre l'architecture ARM et les architectures 32 et 64 bits, intéressons-nous à la raison d'être de l'architecture ARM. Parce qu'en soi, les architectures 32 et 64 bits, ça fait très bien le travail sur les ordinateurs actuels !

Apparition de contraintes supplémentaires : pourquoi l'architecture ARM est-elle née ?

L'histoire de l'architecture ARM a commencé avec l'apparition des ordiphones (ou smartphones, si vous préférez). En effet, il existe une différence majeure entre un ordiphone et un ordinateur, au niveau de la dissipation de chaleur : un ordiphone n'est pas équipé de ventilateur !

Ceci est un problème particulièrement contraignant parce que, comme chacun sait, tout composant électronique chauffe par un procédé nommé Effet Joule. On est donc obligé de le refroidir si l'on ne veut pas qu'il brûle (ce qui serait légèrement ennuyeux pour la suite des opérations tout de même...). Sur un ordinateur, on utilise pour cela un ventilateur qui vient envoyer de l'air frais sur le processeur pour le refroidir.

Sur un ordiphone, ce ventilateur est absent. La dissipation de chaleur se fait alors par diffusion, qui est un phénomène nettement moins efficace que la convection obtenue avec un ventilateur : la dissipation de chaleur est assez mauvaise ! Aussi il a été indispensable de créer une nouvelle famille de processeurs qui limiterait l'effet Joule. De plus, les ordiphones doivent être économes en énergie pour respecter des critères d'autonomie sur batterie, par conséquent s'il y a moyen d'économiser un peu d'énergie, c'est toujours bon à prendre. On a donc aussi cherché à créer des processeurs plus économes en énergie.

C'est entres autres pour répondre à ces problématiques que l'architecture ARM est née.

Repenser les processeurs avec l'architecture ARM : simplifier pour moins chauffer

Afin d'éviter de produire trop de chaleur, la solution la plus efficace reste toujours de réduire le nombre de composants électroniques. C'est ce que les concepteurs de l'architecture ARM ont fait, et pour garder leurs processeurs assez rapides, ils ont dû changer de nombreuses choses par rapport à un processeur de bureau, où le seul but est la puissance, quitte à produire énormément de chaleur !

Tout d'abord, le jeu d'instructions du processeur a été simplifié : là où auparavant certaines instructions en Assembleur x86 étaient assez alambiquées, toutes les instructions des processeurs ARM réalisent des tâches simples. On parle de RISC (Reduced Instruction Set Computer : Processeur à jeu d'Instructions Réduit) pour désigner les architectures où le jeu d'instructions est simplifié (comme l'ARM) alors que l'on parle de CISC (Complex Instruction Set Computer : Processeur à jeu d'Instructions Complexes) pour les langages un peu plus étoffés comme l'Assembleur x86.

Le jeu d'instructions RISC étant plus simple, son implémentation requiert moins de composants électroniques. Cela permet de limiter l'effet Joule, et d'utiliser l'énergie de manière plus efficace étant donné qu'il y a moins de composants à alimenter. Par ailleurs, étant donné qu'il y a moins de composants, les instructions RISC sont traitées plus rapidement. Mais on peut parfois être amené à en utiliser plusieurs pour avoir le même résultat qu'avec une seule instruction CISC, le processeur CISC est alors plus rapide pour arriver au même résultat.

Ainsi, les processeurs ARM, au profit d'une consommation et d'un effet Joule moindres, sont généralement moins puissants que les processeurs de nos ordinateurs (voire carrément plus lents pour économiser l'énergie). Et cette différence de performance, elle est flagrante pour des tâches plus exigeantes, comme la vidéo. C'est ce que l'on a vu lorsque l'on a essayé de faire tourner Kodi dans l'environnement de bureau : comme Kodi est plus lourd graphiquement que l'environnement de bureau, il était terriblement lent!

Où est passée la carte graphique ?

La gestion de l'affichage est une tâche requérant une grande partie des calculs réalisés par votre ordinateur, en particulier lorsqu'il faut afficher des objets en 3D (quand vous jouez à un jeu vidéo en 3D, n'entendez-vous pas les ventilateurs s'affoler, montrant qu'il y a plus d'activité dans les composants de votre ordinateur ?). Le plus souvent, les calculs se ressemblent. Aussi il est possible, si l'on sépare le circuit en charge de cela, de gagner un temps phénoménal par rapport à un traitement par le processeur.

Cette séparation est visible sur tous les ordinateurs, qui sont équipés d'une puce, nommée carte graphique, chargée de réaliser tous les calculs liés à l'affichage. Toutefois, il existe différents modèles de cartes graphiques ayant des capacités différentes. Ainsi, une instruction qui fonctionnera avec un modèle ne marchera pas nécessairement sur un autre, et inversement. C'est pour cela que, lorsque l'on installe un système d'exploitation, l'affichage est le plus souvent moche au début. En effet, le système d'exploitation ne sachant pas comment exploiter la carte graphique, il va se contenter de l'ignorer et reporter tous les calculs sur le processeur. Cela dure jusqu'à ce que l'on installe un programme (le pilote de la carte graphique) qui gère cette communication, permettant ainsi d'exploiter la carte graphique au meilleur de ses capacités.

Le pilote, justement, parlons-en ! Comme vous devez vous en douter, chaque programme ne s'adapte pas au pilote installé, il existe un standard de communication ! On peut citer le très célèbre DirectX sous Windows, mais aussi OpenGL qui est quant à lui multi-plateformes. Le rôle du pilote est de convertir toutes les instructions OpenGL en instructions compréhensibles par la carte graphique, afin que celle-ci puisse effectuer les calculs demandés.

Mais, tout comme le processeur, ce composant chauffe. Et, sur les systèmes utilisant l'architecture ARM, ce composant, pourtant si important pour que l'image soit fluide, n'existe pas afin d'éviter de chauffer encore plus. Et ça, Kodi nous l'a bien montré lorsque j'ai essayé de le lancer directement, sans environnement graphique, avec son message où il demande un composant capable de faire du rendu OpenGL. La carte graphique n'étant pas présente sur mon micro-ordinateur, il n'était pas possible d'avoir un composant capable de faire du rendu OpenGL, ce qui a fortement déplu à Kodi comme on a pu le voir ! Le lancement dans un environnement graphique déjà établi est sensiblement différent, puisque Kodi va dans ce cas faire directement appel aux fonctions de l'environnement et pas du matériel (afin de s'intégrer dans l'environnement avec une fenêtre par exemple).

Gestion des graphismes par l'ARM

Sans carte graphique, tous les calculs pour gérer l'affichage retombent sur le processeur qui, n'étant pas optimisé pour cela, est plus lent. Cela dit, il a bien fallu trouver une astuce pour que l'on puisse aussi faire des jeux en 3D sur ordiphone. On a donc décidé d'intégrer dans le processeur un circuit capable de faire les calculs graphiques rapidement (on peut citer par exemple les circuits Mali). C'est l'un des points forts de l'architecture ARM : elle est extrêmement flexible, et il est ainsi possible de tout faire avec une seule puce!

Mais, comme pour une carte graphique, ces circuits ont un langage bien particulier, et il n'existe parfois pas de pilotes Linux pour ceux-ci alors qu'il existe des pilotes pour Android. Bien qu'Android et Linux soient similaires, il y a des différences dans la gestion du multimédia entre les deux systèmes, et on ne peut pas directement porter les pilotes Android sous Linux. De plus, le code source de ces pilotes Android n'est parfois pas Open Source, ce qui rend encore plus difficile les tentatives de portage d'Android à Linux. Ainsi, je n'avais pas de pilote graphique disponible sous Linux pour mon Odroid-XU...

Solutions Linuxiennes au problèmes ARMiens

Graphismes

Heureusement pour nous, il existe un projet ayant pour ambition de permettre l'utilisation de la plupart des pilotes graphiques d'Android sous Linux), nommé libhybris. A l'aide de ce merveilleux outil, il est possible d'avoir un semblant d'OpenGL, pile ce dont on a besoin !

Mais il y a toujours un petit truc en plus dont on a besoin, sinon c'est pas drôle ! Ici, c'était la distribution Android pour mon système, et avec les sources s'il vous plaît ! Bon je me suis pas trop plongé dans les détails, quelqu'un d'autre l'avait déjà fait pour moi. Une petite correction de bug et c'était bon bon, j'avais la librairie de compilée.

Cela n'a toutefois pas suffit à tout faire marcher du premier coup ! Il manquait en effet un petit programme pour gérer notre petit circuit graphique. Heureusement, quelqu'un s'était déjà confronté au problème, et avait eu la bonne idée de partager les fichiers dont on a besoin pour que tout fonctionne. Une fois tout cela installé à la racine, et quelques petits détails réglés pour les fichiers (parce que, évidemment, l'organisation des fichiers change un peu d'Android à Linux...), le programme a accepté de démarrer, et les tests d'affichage fonctionnaient.

Cependant, libhybris est un programme un petit peu particulier (faut dire que le matériel l'est aussi un peu !) et on ne l'utilise donc pas comme une carte graphique classique. Aussi, le code de Kodi avait besoin d'une petite adaptation pour fonctionner correctement...

Mais Kodi est bien fait : il sait s'adapter aux différentes manières de parler aux cartes graphiques. En effet, Kodi est multi-plateformes et, comme vous pouvez vous en douter, Linux et Windows ont une manière légèrement différente de permettre l'utilisation des cartes graphiques. Aussi, le code de Kodi avait déjà été prévu pour supporter plusieurs cartes graphiques, comme on peut le voir dans le code source. En rajoutant un dossier (ici, egl) avec tout le code pour utiliser libhybris, on arrange tout, et Kodi arrive à utiliser libhyris. Nous voilà avec une interface fluide !

Décodage vidéo

Mais comme un problème ne vient jamais seul, la faible puissance de mon processeur ARM s'est vite faite remarquer lorsqu'il a fallu lire une vidéo : c'était très lent !

Une histoire d'encodage...

Pour comprendre le pourquoi du comment, un point s'impose sur les manières de stocker les fichiers vidéo. En effet, afin d'éviter d'avoir des fichiers trop volumineux, on compresse les vidéo à l'aide d'un petit programme (x264 par exemple). C'est très pratique, car sans cela on aurait des fichiers vraiment énormes : un film en Full HD non compressé (c'est ce que l'on trouve sur les BluRay) prend près de 40 Go, alors que l'on peut le compresser jusqu'à une dizaine de Gigaoctets sans avoir de perte de qualité visible !

Le revers de la médaille, c'est que cette compression requiert un peu plus de travail lorsque l'on veut lire la vidéo : au lieu d'avoir directement l'image, on va avoir des informations dessus, et il va falloir la reconstituer. C'est comme les fichier RAW des appareils photo (qui contiennent les informations sur les pixels bruts) et leur conversion en JPEG (qui est une version compressée de l'image).

Pour reconstituer l'image, il est possible de faire appel à la carte graphique si celle-ci est équipée d'un circuit pour décoder la vidéo. C'est la méthode que l'on essaye de préférer, car elle est plus rapide (on parle d'accélération matérielle). Mais, comme vous pouvez vous en douter, il faut que celle-ci soit bien connue du système d'exploitation : pilote approprié obligatoire !

Si la méthode ci-dessus n'est pas disponible (pilote absent ou compression non prise en charge par la carte graphique par exemple), c'est au processeur que l'on fait appel pour reconstituer l'image. On parle alors de décodage logiciel, car il est nécessaire d'utiliser un programme qui va faire les calculs un par un. L'un des logiciels les plus utilisés pour cela est FFmpeg, qui présente l'intérêt d'être Open Source, et qui supporte un grand nombre de compressions vidéo.

Retour sur notre micro-ordinateur

Et notre micro-ordinateur, alors ? Hé bien, comme vous pouvez vous en douter, l'accélération matérielle n'était pas utilisée, et c'était au processeur de faire tous les calculs. Sur un ordinateur de bureau, cela peut se passer sans problème. Mais sur un processeur ARM nettement moins puissant, c'était trop lent, d'où les problèmes d'image.

Mais quand on lit une vidéo sur un ordiphone, c'est fluide me direz-vous ! Et vous avez raison, car il y a comme pour les graphismes un petit circuit qui a été prévu afin d'accélérer le décodage vidéo sur notre micro-ordinateur ! Ici, c'est un circuit dénommé MFC, pour Multi Function Codec. C'est un circuit propriétaire, donc il n'y a pas énormément d'informations dessus de la part de Samsung, mais il y a assez pour que Linux soit capable de l'utiliser. Et si Linux est capable de s'en servir, c'est que Kodi peut aussi le faire, pour avoir une vidéo fluide !

Comme d'habitude, il faut adapter un peu le code de Kodi. Mais le code était déjà assez flexible pour supporter quelques ajouts, étant donné qu'il y avait déjà eu des choses de faites sur l'accélération matérielle. En ajoutant des fichiers pour la prise en charge du MFC au bon endroit, on permet à Kodi d'exploiter le circuit à disposition.

Cela dit, j'avais déjà compilé ce code, et ça ne marchait pas pour autant. En effet, il y a plusieurs versions du circuit MFC sur le marché, et Linux ne sait pas vraiment lequel choisir. Dans notre cas, copier le fichier /usr/lib/firmware/s5p-mfc-v6-v2.fw à l'emplacement /usr/lib/firmware/mfc_fw.bin règle le problème, et on a ainsi une lecture fluide des vidéos, comme avec les versions distribuées sur le forum !

Conclusion

Comme vous avez pu le voir, la mise en place de tout cela n'était pas de tout repos. Mais après tout c'était écrit sur la boîte : Do it yourself, faites-le vous-même !

Illustration

On peut se demander si ça valait vraiment le coup de tout faire soi-même, alors que l'on sait que des solutions existent déjà.

Pour ma part, je pense que ça vaut le coup, et ce pour plusieurs raisons.

Tout d'abord, ce petit cheminement m'a permis de comprendre un peu plus la technique qu'il y a dans un ordinateur, et en particulier dans les ordiphones. C'est assez incroyable que ça soit aussi compliqué, mais que l'on ne se rende compte de rien quand on a un ordiphone dans les mains !

De plus, tout faire soi-même permet d'avoir un système qui peut remplir toutes les fonctionnalités que l'on veut. En l'occurence, en plus de faire lecteur multimédia, mon micro-ordinateur a aussi les casquettes de serveur de fichiers de serveur Web ! Je ne pense pas que l'on puisse atteindre un tel niveau de personnalisation avec un boitier vendu comme lecteur multimédia.

Enfin, il est clair que certains périphériques ont une communauté bien plus importante, ce qui simplifie énormément l'installation de Kodi. Je pense notamment à la Raspberry Pi, ou à l'Odroid-C1 d'Hardkernel, qui a un paquet Kodi présent sur les dépôts officiels d'ArchLinuxARM. Ici, il est presque miraculeux que quelqu'un se soit intéressé à l'adaptation de Kodi pour ce micro-ordinateur. Je n'aurais jamais été capable de le faire tout seul, alors merci Oversun ! Ainsi, si vous voulez investir dans un micro-ordinateur ARM afin d'en faire un lecteur, je ne peux que vous encourager à le faire, mais je vous conseille de faire attention au support qu'il y a derrière, afin que ça ne soit pas la galère pour tout faire marcher, comme ça a été mon cas !

Pour aller plus loin

Si vous souhaitez approfondir un peu les différences entre les processeurs de nos ordinateurs et les processeurs ARM, je ne peux que vous recommander cet article de LaRuche sur lequel je me suis appuyé lors de mon énumération des différences entre les deux architectures.