Questions sur les kernelx du kernel Linux

Je lisais "pilotes de périphériques Linux, 3ème édition" et fait face à quelques éléments du kernel que je ne comprends pas très bien. Les gourous d'espoir sur ce forum m'aideront.

  1. Le kernel Linux fonctionne-t-il en interne avec des adresses virtuelles ou physiques? Ce qui me déroute particulièrement, c'est qu'il y a plusieurs types d'adresses (logique, virtuel, bus et physique) et qu'ils sont tous valides et exploitables par le kernel.

  2. Est-il exact que les instructions du CPU ne peuvent pas adresser directement datatables stockées dans les périphériques et donc que la memory adressable est utilisée, c'est-à-dire les tampons, à ces fins?

  3. Un process peut-il dormir en demandant un sémaphore (qui a une valeur 0) et doit l'attendre?

  4. Opérations atomiques – sont-elles garanties par des instructions CPU spécifiques?

Il vaut mieux ne pas poser plusieurs questions à la fois car tout le monde ne peut pas ou ne veut pas tout répondre. Encore, je vais donner une réponse courte à chacun.

Le kernel Linux fonctionne-t-il en interne avec des adresses virtuelles ou physiques? Ce qui me déroute particulièrement, c'est qu'il y a plusieurs types d'adresses (logique, virtuel, bus et physique) et qu'ils sont tous valides et exploitables par le kernel.

Oui. Différentes parties du kernel utilisent des espaces d'adresses différents.

Tandis que le code du kernel traite un appel système, ses mappages de memory incluent à la fois l'espace memory du kernel entier et tout l'espace memory du process (à less que votre kernel ait une memory haute configurée, mais c'est trop compliqué). Ce sont toutes des adresses logiques (alias virtuelles): les bits de poids fort de l'adresse indiquent quelle page chercher dans la MMU , et les bits de poids faible sont une adresse linéaire à l'intérieur de la page. Les mappages de memory à l'intérieur de la MMU changent chaque fois qu'un changement de tâche se produit (la modification de la table de pages dans la MMU est une grande partie d'un commutateur de tâche).

Certains pilotes de périphériques doivent manipuler les adresses memory valides pour le périphérique qu'ils conduisent. Ce sont souvent des adresses physiques, bien que certaines architectures aient un IOMMU, de sorte que les périphériques voient aussi leurs propres adresses logiques. Bien sûr, le sous-système de memory management dans le kernel doit manipuler beaucoup de différents types d'adresses.

Est-il exact que les instructions du CPU ne peuvent pas adresser directement datatables stockées dans les périphériques et donc que la memory adressable est utilisée, c'est-à-dire les tampons, à ces fins?

Ceci dépend de l'architecture. La plupart des architectures ont une sorte de DMA (access direct à la memory) , ce qui permet au less une certaine communication avec les périphériques via RAM. En outre, sur certaines architectures (ARM, par exemple), tous les access aux périphériques sont effectués avec des instructions de chargement et de stockage à des adresses appropriées, tandis que d'autres (par exemple, i386) ont des instructions spécifiques à cet effet. Voir E / S mappées en memory pour plus de détails.

Un process peut-il dormir en demandant un sémaphore (qui a une valeur 0) et doit l'attendre?

Oui, prendre un sémaphore ( down et amis) est une opération de blocage. Ceci est bien expliqué dans le livre.

Opérations atomiques – sont-elles garanties par des instructions CPU spécifiques?

Oui. Les détails sont très spécifiques à l'architecture. Toutes les plates-forms destinées au multitâches fournissent au less une primitive atomique pour la synchronisation, telle que la comparaison et l'échange , le test et l'établissement , la binding de charge + le stockage conditionnel , etc. En plus de l'utilisation de la primitive correcte, le code peut avoir besoin de prendre soin d'utiliser des barrières de memory appropriées sur les systèmes multiprocesseurs. Le kernel Linux fournit une implémentation de ses primitives de synchronisation pour chaque architecture supscope, de sorte que vous n'utilisez à leur tour que les primitives portables du kernel.

Je peux essayer de répondre 1,3 et 4.

Le kernel Linux utilise différentes étapes pour transposer le code du programme en signaux élecsortingques.

Adresse logique : celles-ci sont incluses dans les instructions du langage machine pour adresser une opération ou une instruction. Divisé en segment et en décalage.

Adresse linéaire : L'unité de segmentation traduit les adresses logiques en adresses linéaires. C'est un nombre hexadécimal (sur l'architecture 32bit: 0x00000000-0xffffffff ) adressant l'espace en memory.

Adresse physique : En outre, l'unité de pagination convertit le linéaire en adresses physiques. Ce sont des signaux élecsortingques adressant des cellules memory sur des broches sur des microprocesseurs.

Adresse de bus : Utilisé par tous les périphériques matériels à l'exception de la CPU pour adresser les cellules de memory (DMA ne nécessite pas la CPU, mais toujours l'adressage). Ces adresses sont pour la plupart identiques à celles physiques, sauf sur d'autres architectures, comme SPARC et Alpha, qui include une unité de gestion de memory d'E / S distincte.

Le kernel fonctionne avec toutes les adresses, et chacun d'entre eux est un pas entre la request d'un user et le traitement de cette requête au niveau matériel.


Si un process approche un sémaphore de valeur 0 ou inférieure, il est suspendu jusqu'à ce que la valeur atteigne 1 ou plus. Cela se produit uniquement pour les process qui peuvent dormir. Un gestionnaire d'interruption ne peut pas dormir et il est donc interdit d'utiliser des sémaphores.


Les opérations atomiques peuvent être réalisées en utilisant les instructions du langage d'assemblage, celles-ci sont définies par:

  • Zéro ou un access memory
  • Préfixé avec LOCK_PREFIX

Au niveau C, le kernel fournit le type atomic_t et les macros préfixées par atomic_
(qui ajoutent LOCK_PREFIX aux instructions d'assemblage).