À qui appartient cette adresse physique ?

Memory Controller, IO Controller, Memory-mapped IO, etc.

Le problème exposé dans ce sujet a été résolu.

(désolé pour le titre du sujet, je n'ai pas réussi à trouver quelque chose de plus parlant)

Bonjour à tous,

J'ai une petite question toute bête sur un détail auquel je n'ai pas encore réussi à trouver de réponses claires (j'ai un peu honte é_é). Du coup j'inaugure. Ma question concerne en particulier l'architecture x86.

Une fois que le CPU a récupéré l'adresse physique correspondant à ce qu'il manipule, dans la plupart des architectures contemporaines, il fait une requête Memory Controller (qui, dans les architectures les plus récentes, est compris dans le CPU). Ce Memory Controller doit déterminer si cette adresse physique correspond, dans sa memory map, à une adresse en RAM ou à une mémoire d'un périphérique mappé en mémoire.

Ma question est fort simple, en fait : comment est gérée cette mémoire externe mappée en mémoire (la Memory-Mapped IO) ? Est-ce que c'est décidé de façon statique et fixé dans la doc du contrôleur ? Est-ce que ça peut être fait de manière plus dynamique (et dans ce cas là, comment ?).

Je sais que les devices PCI ont des Base Address Registers pour faire ça dynamiquement au niveau du Bus PCI, mais j'imagine que la plage d'adresse qui leur est assignée est limitée par l'IO Controller ?

Voilà, c'est des questions qui me paraissent super naïves mais en même temps, j'aimerai bien avoir les réponses et j'ai du mal à m'y retrouver dans les ressources que je trouve sur le net.

+0 -0

Salut lethom,

La réponse à ta question m'intéresse. Je pense que tu la connais déjà.

Selon moi, le processeur passe effectivement par un contrôleur physique qui ira "activer" le périphérique correspondant (RAM, ROM…) à l'adresse physique concernée.

Par exemple, si tu tapes dans une adresse comprise entre 0x0000 et 0x0FFF, ça serait la ROM. Si c'est de 0x1000 à OxFFFF, ça serait la RAM, etc.

J'avoue que la réponse reste vague, mais il me semble que ça fonctionne tel quel.

+0 -0

Merci pour ta réponse. Je suis d'accord sur le principe. Je me demande juste comment se débrouille le « dispatcher ».

Par exemple, si tu tapes dans une adresse comprise entre 0x0000 et 0x0FFF, ça serait la ROM. Si c'est de 0x1000 à OxFFFF, ça serait la RAM, etc.

Du coup, les plages d'adresse sont bien spécifiées en dures dans les specs des différents contrôleurs ?

+0 -0

Alors je pense que le dispatcher c'est en fait une combinaisons de portes logiques. Dans mon exemple il va vérifier si le bit 12 (0000 0000 0000 0000) est à 1. Si c'est le cas, il pioche dans la RAM. Sinon, il pioche dans la ROM. C'est bien ça que tu cherches à savoir ?

Je ne saurais répondre à ta seconde question. J'avoue que j'aimerais bien savoir également. Gwenn, mewtwo, si vous passez par là…

+0 -0

Dans tous les cas, ton architecture/chipset/contrôleur mémoire contient une memory map, une véritable carte qui indique la répartition des adresses.

Elle est où cette memory map ?

Dans le cas le plus simple, où tu n'as pas de chipset ou de contrôleur mémoire, la memory map est implicite : elle est implémentée avec un décodeur

Sur les architectures plus évoluées, la memory map et les tests d'intervalle sont pris en charge par :

  • le chipset (si il n'est pas découpé en chipset nord et sud) ;
  • les chipset nord et sud : les deux contiennent une partie de la memory map et s'occupent tous deux d'une partie du processus de répartition des adresses ;
  • le contrôleur mémoire intégré au processeur et le chipset sud.

Implémentation matérielle

Le circuit de gestion de la memory map est composé (sur le principe) de deux parties :

  • une qui contient la memory map et qui se charge de détecter dans quel intervalle tombe une adresse ;
  • une autre qui se charge , une fois l'intervalle connu, de choisir le bon bus.

Dans certains cas, ces deux circuits sont fusionnés en un seul circuit.

Memory Map

Généralement, la memory map est composée d'un ensemble de comparateurs qui vérifie si l'adresse à lire tombe dans tel ou tel intervalle : on retrouve autant de comparateurs qu'il y a d'intervalles (sauf éventuelles optimisations).

Si certains de ces intervalles sont câblés en dur, le décodeur/chipset/contrôleur mémoire peut permettre de configurer les intervalles qui doivent l'être. Pour cela, il doit forcément contenir des registres qui permettent de mémoriser le début et la fin des intervalles, un peu comme pour les bus PCI. Par exemple (inventé, l'exemple), pour placer le PCI-Express entre les adresses 0xFFFFF000 et 0xFFFFF0FF, il suffit de configurer deux registres : un de fin, un de début.

Évidemment, ces registres ont tous une certaine limite, et ne peuvent pas prendre toutes les valeurs (des sécurités sont ajoutées pour éviter cela : il suffit de vérifier la validité des intervalles avec quelques comparateurs, et de lever une interruption en cas d'écriture d'un intervalle invalide dans ces registres.

Pour te donner un exemple, tu peux lire le datasheet du chipset Intel G35 : Datasheet du chipset G35. La partie 3 décrit la memory map cablée, et la 4 décrit les registres qui permettent de configurer les parties variables de la memory map.

Dispatcher

Pour le circuit qui se charge de répartir la requête mémoire sur les bus une fois l'intervalle connu, il varie suivant le système. Dans le cas le plus simple, ce doit être un simple multiplexeur. Dans les cas les plus complexe, il s'agit d'une portion complète de chipset (voire d'un ensemble de chipset : un nord, et un sud).

+5 -0

Okok, impeccable ! Merci beaucoup pour ces précisions, c'était les engrenages qui me manquaient pour que ça coule bien dans ma tête.

Autre question pendant que j'y suis : au sujet des ports IO (donc, espace d'adresses séparé). Dans les specs que j'ai pu lire, ils sont écrits « en dur ». Par exemple, le registre APMC correspond au port 0xb2 et je peux très simplement écrire dedans avec l'instruction assembleur out. Soit. En l'occurrence, le port 0xb2 est dans le contrôleur mémoire, donc c'est assez safe, mais est-ce qu'il serait possible que deux devices exposent un port aux mêmes adresses ?

+0 -0

Logiquement, on évite au maximum le partage d'adresse entre périphériques, sauf dans quelques cas exceptionnels. Les périphériques/IO sont configurables, voire conçus pour éviter ce genre de situation : on peut configurer leurs plages d'adresses dans l'espace IO pour éviter ce genre de choses.

+0 -0

Je suis d'accord sur le « fonctionnement normal », je m'intéresse plus aux cas limites avec un device pas forcément bienveillant (qui pourrait, a priori, mentir). Mais je ne savais pas que l'espace IO était configurable. Merci !

+0 -0

Pour les cas frauduleux ou buggés, je ne sais pas trop comment cela se passe.

Une chose est sure : il y a un risque que plusieurs devices accèdent en même temps au bus en écriture, ce qui peut ne pas être possible électriquement, ou être géré par un système d'arbitrage ou le chipset. Il y a surement possibilité que le périphérique frauduleux profite de l'algorithme d'arbitrage pour autoriser ses écritures, mais je ne parierais pas dessus.

Pour les lectures, cela dépend du bus et de ses caractéristiques électriques, mais il y a possibilité que le périphérique frauduleux puisse espionner ce qui se passe sur le bus.

De mémoire, il n'y a pas des conflits de plage d'adresse DMA sur les anciens PC qui correspondent à ce genre de cas ? C'était une cause de périphériques non-reconnus sous certaines anciennes versions de Windows, si je dis pas de conneries.

Réponse au HS : Mes schémas, c'est du Paint version XP ou Windows 8 (ça dépend du PC que j'utilise).

+0 -0

Je ne sais pas très bien ce qu'il en est sur un PC aujourd'hui, mais il y a de bonnes chances que ce soit comme sur les téléphones portables, tablettes, … Aujourd'hui, sur un système à base de cœur ARM, il n'y a plus réellement un bus mémoire. A la place, on retrouve une IP nommée Interconnect, qui va fournir une interface par maitre (par cœur processeur, notamment), et par esclave (chipset graphique, contrôleur mémoire, …). Un même device peut avoir à la fois une interface maître et une interface esclave sur le bus (c'est le cas par exemple des chipset graphiques, qui vont aussi avoir besoin d'être maîtres vis-à-vis de la mémoire).

L'interconnect va gérer beaucoup de choses : les accès concurrents au même esclave par des maîtres différents, les problèmes de "salissure" (quand les caches deviennent dirty), de cohérence et de transferts de caches, … Leur présence permet aussi d'éviter qu'un élément espionne les transferts effectués entre deux autres. C'est la base de l'extension de sécurité ARM TrustZone, par exemple.

Le SoC est synthétisé avec des valeurs d'initialisation pour l'interconnect, qui va ensuite gérer les consignes invalides (par exemple en figeant toutes les transactions, ce qui peut ne laisser comme solution que de re-démarrer le SoC). Le device n'a in-fine aucun contrôle sur la plage d'adresse qu'il occupe sur le bus.

PS : je sais que le sujet date un peu, mais comme j'avais quelques billes pour aller avec celles de mewtow, j'ai essayé de compléter la réponse

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte