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.