Portage de Linux sur une autre plate-forme requise [fermé]

28

Je sais que Linux est disponible et a été porté sur de nombreuses plates-formes différentes telles que X86, ARM, PowerPC, etc.

Cependant, en termes de portage, que faut-il exactement?

Ma compréhension est que Linux est un logiciel écrit en C. Par conséquent, lors du portage de Linux à l'origine de X86 vers ARM ou d'autres par exemple, ne s'agit-il pas simplement de recompiler le code avec le compilateur pour l'architecture cible spécifique?

Mis à part les pilotes de périphériques pour différents périphériques, quoi d'autre devrait être fait lors du portage de Linux vers une nouvelle architecture. Le compilateur ne s'occupe-t-il pas de tout pour nous?

Ingénieur999
la source
11
Pouvons-nous supposer que vous avez examiné les sources du noyau spécifiques à l'architecture? git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/…
Kusalananda

Réponses:

57

Même si la plupart du code du noyau Linux est écrit en C, il existe encore de nombreuses parties de ce code qui sont très spécifiques à la plate-forme sur laquelle il s'exécute et doivent en tenir compte.

Un exemple particulier de cela est la mémoire virtuelle, qui fonctionne de la même manière sur la plupart des architectures (hiérarchie des tables de pages) mais a des détails spécifiques pour chaque architecture (comme le nombre de niveaux dans chaque architecture, et cela a même augmenté sur x86 avec introduction de nouvelles puces plus grandes.) Le code du noyau Linux introduit des macros pour gérer la traversée de ces hiérarchies qui peuvent être élidées par le compilateur sur des architectures qui ont moins de niveaux de tables de pages (de sorte que le code est écrit en C, mais prend les détails de l'architecture en considération.)

De nombreux autres domaines sont très spécifiques à chaque architecture et doivent être traités avec du code spécifique à l'archive. La plupart d'entre eux impliquent cependant du code en langage assembleur. Voici des exemples:

  • Commutation de contexte : La commutation de contexte implique la sauvegarde de la valeur de tous les registres pour le processus en cours de désactivation et la restauration des registres de l'ensemble enregistré du processus planifié dans la CPU. Même le nombre et l'ensemble de registres sont très spécifiques à chaque architecture. Ce code est généralement implémenté dans l'assembly, pour permettre un accès complet aux registres et également pour s'assurer qu'il s'exécute le plus rapidement possible, car les performances de la commutation de contexte peuvent être critiques pour le système.

  • Appels système : le mécanisme par lequel le code de l'espace utilisateur peut déclencher un appel système est généralement spécifique à l'architecture (et parfois même au modèle de processeur spécifique, par exemple Intel et AMD ont introduit des instructions différentes pour cela, les anciens processeurs peuvent ne pas avoir ces instructions, donc les détails car ceux-ci seront toujours uniques.)

  • Gestionnaires d'interruptions : les détails sur la façon de gérer les interruptions (interruptions matérielles) sont généralement spécifiques à la plate-forme et nécessitent généralement une colle au niveau de l'assembly pour gérer les conventions d'appel spécifiques utilisées pour la plate-forme. De plus, les primitives pour activer / désactiver les interruptions sont généralement spécifiques à la plate-forme et nécessitent également un code d'assembly.

  • Initialisation : Les détails sur la façon dont l'initialisation doit se produire incluent généralement des détails spécifiques à la plate-forme et nécessitent souvent un code d'assembly pour gérer le point d'entrée vers le noyau. Sur les plates-formes qui ont plusieurs processeurs (SMP), les détails sur la façon de mettre en ligne d'autres processeurs sont également spécifiques à la plate-forme.

  • Verrouillage des primitives : la mise en œuvre de primitives de verrouillage (telles que les verrous tournants) implique généralement des détails spécifiques à la plate-forme, car certaines architectures fournissent (ou préfèrent) différentes instructions CPU pour les implémenter efficacement. Certains implémenteront des opérations atomiques, certains fourniront un cmpxchg qui peut tester / mettre à jour atomiquement (mais échouera si un autre écrivain est entré en premier), d'autres incluront un modificateur "lock" aux instructions CPU. Celles-ci impliquent souvent également l'écriture de code d'assembly.

Il y a probablement d'autres domaines où du code spécifique à la plate-forme ou à l'architecture est nécessaire dans un noyau (ou, plus précisément, dans le noyau Linux.) En regardant l'arborescence des sources du noyau, il y a des sous-arbres spécifiques à l'architecture sous arch/et sous include/arch/où vous pouvez trouver plus des exemples de cela.

Certains sont en fait surprenants, par exemple, vous verrez que le nombre d'appels système disponibles sur chaque architecture est distinct et que certains appels système existeront dans certaines architectures et pas dans d'autres. (Même sur x86, la liste des appels système diffère entre un noyau 32 bits et un noyau 64 bits.)

En bref, il y a beaucoup de cas qu'un noyau doit connaître et qui sont spécifiques à une plate-forme. Le noyau Linux essaie d'abstraire la plupart de ceux-ci, donc des algorithmes de plus haut niveau (comme le fonctionnement de la gestion et de la planification de la mémoire) peuvent être implémentés en C et fonctionner de la même manière (ou presque la même) sur toutes les architectures.

filbranden
la source
7
Très belle rédaction! La variation du nombre d'appels système est principalement liée à l'histoire: les nouveaux ports incluent les appels système valides au moment du port, ils ne se soucient pas des bagages historiques présents dans les ports plus anciens, de sorte que les appels système obsolètes ne sont généralement pas présents dans les ports plus récent que la dépréciation. (Cela ne couvre pas tous les scénarios ...)
Stephen Kitt
10

En plus de porter le noyau Linux, vous devrez définir l' interface binaire d'application (ABI) pour les programmes "espace utilisateur" et porter les couches les plus basses de la pile logicielle de l'espace utilisateur. Linux est généralement utilisé avec des composants d'espace utilisateur de bas niveau du projet GNU, dont les plus critiques sont:

  • Le compilateur C, l'assembleur et l'éditeur de liens: GCC et GNU Binutils . Pour une architecture CPU entièrement nouvelle, vous devez porter ce logiciel avant même de commencer à porter le noyau, car le noyau est lui-même un programme C et doit être compilé. S'il existe déjà une prise en charge «back-end» pour le processeur de votre plate-forme, mais pas avec Linux en tant que noyau du système d'exploitation, vous avez beaucoup moins de travail à faire et vous pourrez peut-être vous contenter de reporter la plupart du travail jusqu'à ce que le noyau soit en place et fonctionnement.
  • La bibliothèque d'exécution C: " GNU libc ". Cette bibliothèque inclut le code qui effectue des appels système et interagit autrement directement avec le noyau.
  • La bibliothèque "interface de fonction étrangère", libffi , qui est un composant essentiel de nombreux interpréteurs de langage de haut niveau, et effectue l'une des rares tâches restantes qui nécessite une petite quantité de langage d'assemblage manuscrit.

De nombreux autres logiciels ont des composants optionnels dépendants de la plate-forme; par exemple, la navigation sur le Web sera considérablement plus rapide si vous écrivez des primitives cryptographiques optimisées à la main pour NSS et OpenSSL pour votre nouvelle architecture de processeur, et des back-ends de compilation juste à temps pour IonMonkey et V8 . Mais ceux-ci ne sont pas essentiels pour mettre en place une nouvelle plate-forme.

zwol
la source
1

Vous devez informer le noyau du matériel sur lequel vous portez. Le travail du noyau est d'interfacer directement avec le matériel, donc pour qu'il fonctionne correctement, le noyau doit connaître le CPU, les oscillateurs (horloges) et tous les périphériques, comme les différents types de ports série (SPI, CAN, I2C, etc.).

Dans l'ancien temps, vous faisiez cela en écrivant du code spécifique à la plate-forme que les pilotes utilisaient ensuite pour fonctionner. De nos jours, cela se fait en écrivant une définition de l'arborescence des périphériques .

Canard en caoutchouc
la source