Fonctionnement d'un ordinateur/L'espace d'adressage du processeur

L'espace d'adressage du processeur correspond à l'ensemble des adresses utilisables par le processeur. Par exemple, si je prends un processeur 16 bits, il peut adresser en tout 2^16 = 65536 adresses et l'ensemble de ces adresses forme son espace d'adressage. L'espace d'adressage n'est pas la mémoire réellement installée : s'il n'y a pas assez de RAM installée, des adresses seront inoccupées. De plus, une partie de l'espace d'adressage peut être détourné pour communiquer avec les périphériques, comme nous le verrons plus bas. Nous verrons aussi dans ce chapitre qu'il est possible qu'un processeur ait plusieurs espaces d'adressages séparés. Et même si cela peut sembler contre-intuitif, nous allons voir que les architectures avec plusieurs espaces d'adressage sont plus simples à comprendre !

Les processeurs avec un seul espace d'adressage modifier

Pour le moment, considérons le cas intuitif où on ne dispose que d'un seul espace d'adressage. Même si on omet les portions inoccupées de l'espace d'adressage, la RAM n'est pas la seule occupante de l'espace d'adressage. On y trouve aussi la mémoire ROM, les périphériques et d'autres choses encore.

Les architectures Von Neumann modifier

Si on n'a qu'un seul espace d'adressage unique, il est utilisé pour adresser non seulement la mémoire RAM, mais aussi la mémoire ROM. On est alors face à une architecture Von Neumann, où un seul espace d'adressage est découpé entre la mémoire RAM d'un côté et la mémoire ROM de l'autre. Une adresse correspond soit à la mémoire RAM, soit à la mémoire ROM, mais pas aux deux. Typiquement, la mémoire ROM est placée dans les adresses hautes, les plus élevées, alors que la RAM est placée dans les adresses basses en commençant par l'adresse 0. C'est une convention qui n'est pas toujours respectée, aussi mieux vaut éviter de la tenir pour acquise.

 
Vision de la mémoire par un processeur sur une architecture Von Neumann.

Les entrées-sorties mappées en mémoire modifier

Sur les ordinateurs avec un seul espace d'adressage, une partie de l'espace d'adressage peut être détourné pour communiquer avec les périphériques. L'idée est que le périphérique se retrouve inclus dans l'ensemble des adresses utilisées pour manipuler la mémoire : on dit qu'il est mappé en mémoire. Les adresses mémoires associées à un périphérique sont redirigées automatiquement vers le périphérique en question. On parle alors d'entrées-sorties mappées en mémoire.

 
IO mappées en mémoire

On remarque ainsi le défaut inhérent à cette technique : les adresses utilisées pour les périphériques ne sont plus disponibles pour la mémoire RAM. Dit autrement, on ne peut plus adresser autant de mémoire qu'avant. La perte peut être très légère ou très importante, en fonction des périphériques installés et de leur gourmandise en adresses mémoires. C'est ce qui causait autrefois un problème assez connu sur les ordinateurs 32 bits, qui ne géraient que 2^32 octets = 4 gibioctets. Certaines personnes installaient 4 gigaoctets de mémoire sur leur ordinateur 32 bits et se retrouvaient avec « seulement » 3,5 à 3,8 gigaoctets de mémoire, les périphériques prenant le reste. Et mine de rien, quand on a une carte graphique avec 512 mégaoctets de mémoire intégrée, une carte son, une carte réseau PCI, des ports USB, un port parallèle, un port série, des bus PCI Express ou AGP, et un BIOS à stocker dans une EEPROM/Flash, ça part assez vite.

Un autre défaut de cette méthode apparait sur les processeurs disposant de mémoire cache. Pour rappel, le cache est une petite mémoire censée accélérer les accès à la mémoire RAM, dans laquelle on stocke des copies des données en RAM. Or, pour le cache, une adresse mémoire est une adresse mémoire: le cache ne sait pas si l'adresse correspond à un périphérique ou non, et il mettra en cache son contenu automatiquement. Mais le problème est que les adresses liées aux périphériques, qui correspondent à des registres ou à la mémoire des périphériques, peuvent être modifiés sans que le cache soit mis au courant. Le périphérique peut à tout instant modifier son état ou sa mémoire interne, ce qui se répercute automatiquement dans l'espace d'adressage, mais rien de tout cela n'est transmis au cache. La solution est que les accès aux périphériques ne doivent pas passer par l’intermédiaire du cache, si on veut qu'ils marchent comme ils le doivent. Cela demande d'adapter le cache et le matériel pour que accès aux périphériques mappés en mémoire contournent le cache. Des adresses, voire des zones entières de la mémoire, sont marquées comme étant non-cachables. Toute lecture ou écriture dans ces zones de mémoire ira donc directement dans la mémoire RAM, sans passer par la ou les mémoires caches.

Nous reparlerons plus en détail des entrées-sorties mappées en mémoire dans un chapitre dédié à l'adressage des périphériques. Aussi, je ne détaillerais pas plus que ça cette technique dans ce chapitre.

La memory map d'un ordinateur avec un seul espace d'adressage modifier

Outre la mémoire RAM principale, des mémoires vidéo et même plusieurs mémoires ROM sont mappées en mémoire. Il y a un unique espace d'adressage qui contient tout ce qui est adressable : toutes les mémoires et tous les périphériques de l'ordinateur. Généralement, les adresses hautes sont réservées aux périphériques et aux mémoires ROM, alors que les adresses basses sont pour la RAM. La ROM est au sommet de l'espace d'adressage, les périphériques sont juste en-dessous, la RAM commence à l'adresse 0 et prend les adresses basses.

 
Espace d'adressage classique avec entrées-sorties mappées en mémoire

Notons que d'autres composants que les périphériques ou les mémoires peuvent se trouver dans l'espace d'adressage. On peut y trouver les horloges temps réels, des timers, des senseurs de température, ou d'autres composants placés sur la carte mère. Un exemple un peu original est le suivant : la console de jeu Nintendo DS incorporait une unité de calcul spécialisée dans les divisions et racines carrées, séparée du processeur, qui était justement mappée en mémoire !

Les premiers micro-ordinateurs et consoles de jeux modifier

Les vielles machines, notamment les premiers ordinateurs comme les Commodores et les Amiga et les vielles consoles de jeux, utilisaient cette méthode pour sa simplicité. Ces machines n'étaient pas comme les ordinateurs personnels, pour lesquels on a une variété de cartes graphiques ou de cartes sons différentes. Tous avaient la même configuration matérielle, le matériel était fourni tel quel, ne pouvait pas être changé ni upgradé. Toutes les commodores 64 avaient exactement le même matériel, par exemple : la même carte son, la même carte graphique, les mêmes périphériques.

Cette standardisation faisait que cela ne servait à rien de limiter l'accès au matériel. De telles machines n'avaient pas de système d'exploitation, ou bien celui-ci était rudimentaire et ne contrôlait pas vraiment l'accès au matériel. Les programmeurs avaient donc totalement accès au matériel et mapper les entrées/sorties en mémoire rendait la programmation des périphériques très simple.

Les PC IBM x86 modifier

Un autre exemple est celui des ordinateurs PC un peu anciens, avec des processeurs x86. A l'époque, les processeurs x86 avaient des adresses de 20 bits, ce qui fait 1 mébioctet de mémoire adressable. Le premier mébioctet de mémoire est décomposé en deux portions de mémoire : les premiers 640 kibioctets sont ce qu'on appelle la mémoire conventionnelle, alors que les octets restants forment la mémoire haute. La mémoire au-delà du premier mébioctet, la mémoire étendue, est apparue quand les processeurs x86 32 bits sont apparus.

  • Les deux premiers kibioctets de la mémoire conventionnelle sont initialisés au démarrage de l'ordinateur. Ils sont utilisés pour stocker le vecteur d'interruption (on expliquera cela dans quelques chapitres) et servent aussi au BIOS. La portion réservée au BIOS, la BIOS Data Area, mémorise des informations en RAM. Elle commence à l'adresse 0040:0000h, a une taille de 255 octets, et est initialisée lors du démarrage de l'ordinateur.
  • Le reste de la mémoire conventionnelle est réservée à la mémoire RAM utilisée par le système d'exploitation (MS-DOS, avant sa version 5.0) et le programme en cours d’exécution.
  • Le bas de la mémoire haute est réservé pour communiquer avec les périphériques. On y trouve les BIOS des périphériques (dont celui de la carte vidéo, s'il existe) , qui sont nécessaires pour les initialiser et parfois pour communiquer avec eux. De plus, on y trouve la mémoire de la carte vidéo, et éventuellement la mémoire d'autres périphériques comme la carte son.
  • Le sommet de la mémoire haute est réservé au BIOS.
  • La mémoire étendue n'est pas réservée pour une utilisation précise.
 
Organisation Mémoire des vieux PC, à l'époque du DOS.

Les processeurs avec plusieurs espaces d'adressages modifier

Il existe des processeurs qui sont capables de gérer plusieurs espaces d'adressage. Cela peut paraitre surprenant, mais nous avons déjà abordé un exemple dans les chapitres précédents (essayez de deviner lequel). Toujours est-il que l'on peut se demander quelle est l'utilité d'avoir plusieurs espaces d'adressage. La raison est pourtant simple, et même intuitive. Avec un seul espace d'adressage, les périphériques et la ROM sont mappés dans l'espace d'adressage. Des adresses censées être disponibles pour la RAM sont détournées vers la ROM ou les périphériques. Si très peu de RAM est installé, alors ce n'est pas un problème : des adresses inutilisées sont détournées pour des choses utiles. Mais si on veut utiliser plus de RAM, les choses se compliquent. L'idée est d'utiliser plusieurs espaces d'adressage dans lesquels on ne met pas la même chose, d'utiliser des espaces séparés pour des utilisations distinctes. On peut par exemple utiliser un espace d'adressage séparé pour la RAM, un autre pour la ROM, un autre pour les périphériques, etc. En dire plus demande de détailler plusieurs techniques qui utilisent chacune un espace d'adressage séparé.

Les architectures Harvard modifier

Le premier cas d'espace d'adressage séparé est celui des architectures Harvard. Pour rappel, avec l'architecture Harvard, on a un espace d'adressage séparé pour la RAM et la ROM. Une même adresse peut correspondre soit à la ROM, soit à la RAM : le processeur voit bien deux mémoires séparées, chacune dans son propre espace d'adressage. Les deux espaces d'adressage n'ont pas forcément la même taille : l'un peut contenir plus de mémoire/adresses que l'autre. Il est par exemple possible d'avoir un plus gros espace d'adressage pour la RAM que pour la ROM. Mais cela implique que les adresses des instructions et des données soient de taille différentes. C'est peu pratique et c'est rarement implémenté, ce qui fait que le cas le plus courant est celui où les deux espaces d'adressages ont la même taille.

 
Vision de la mémoire par un processeur sur une architecture Harvard.

L'espace d'adressage séparé pour les entrées-sorties modifier

Les entrées-sorties et périphériques peuvent avoir leur propre espace d'adressage dédié, séparé de celui utilisé pour la mémoire. Sur ce genre d'architectures, on trouve un espace d'adressage pour la mémoire RAM et la mémoire ROM, et un espace d'adressage spécialisé pour les périphériques et les entrées-sorties.

 
Bit IO.

Une même adresse peut donc adresser soit une entrée-sortie, soit une case mémoire. Et pour faire la différence, le processeur doit avoir des instructions séparées pour gérer les périphériques et adresser la mémoire. Il a des instructions de lecture/écriture pour lire/écrire en mémoire, et d'autres pour lire/écrire les registres d’interfaçage. Sans cela, le processeur ne saurait pas si une adresse est destinée à un périphérique ou à la mémoire. Cela élimine aussi les problèmes avec les caches : les accès à l'espace d'adressage de la RAM passent par l'intermédiaire de la mémoire cache, alors les accès dans l'espace d'adressage des périphériques le contournent totalement.

Là encore, les deux espaces d'adressage n'ont pas forcément la même taille. Il arrive que les deux espaces d'adressage aient la même taille, le plus souvent sur des ordinateurs complexes avec beaucoup de périphériques. Mais les systèmes embarqués ont souvent des espaces d'adressage plus petits pour les périphériques que pour la ou les mémoires. L'implémentation varie grandement suivant le cas, la première méthode imposant d'avoir deux bus séparés pour les mémoires et les périphériques, l'autre permettant un certain partage du bus d'adresse. Nous reviendrons dessus plus en détail dans le chapitre sur l'adressage des périphériques.

Le bank switching modifier

Le bank switching, aussi appelé commutation de banque, permet d'utiliser plusieurs espaces d'adressage sur un même processeur, sans attribuer chaque espace d'adressage pour une raison précise. L'espace d'adressage est présent en plusieurs exemplaires appelés des banques. Les banques sont numérotées, chaque numéro de banque permettant de l'identifier et de le sélectionner.

Le but de cette technique est d'augmenter la mémoire disponible pour l'ordinateur. Par exemple, supposons que j'ai besoin d'adresser une mémoire ROM de 4 kibioctets, une RAM de 8 kibioctets, et divers périphériques. Le processeur a un bus d'adresse de 12 bits, ce qui limite l'espace d'adressage à 4 kibioctets. Dans ce cas, je peux réserver 4 banques : une pour la ROM, une pour les périphériques, et deux banques qui contiennent chacune la moitié de la RAM. La simplicité et l'efficacité de cette technique font qu'elle est beaucoup utilisée dans l'informatique embarquée.

 
exemple de Bank switching.

Cette technique demande d'utiliser un bus d'adresse plus grand que les adresses du processeur. L'adresse réelle se calcule en concaténant le numéro de banque avec l'adresse accédée. Le numéro de la banque actuellement en cours d'utilisation est mémorisé dans un registre appelé le registre de banque. On peut changer de banque en changeant le contenu de ce registre. Le processeur dispose souvent d'instructions spécialisées qui en sont capables.