61 votes

Pourquoi la première instruction du BIOS est-elle située à 0xFFFFFFF0 ("haut" de la RAM) ?

Je sais que le BIOS charge sa première instruction à partir de 0xFFFFFFF0, mais pourquoi cette adresse spécifique ? J'ai un tas de questions et j'espère que vous pourrez m'aider avec certaines d'entre elles, au moins.

Mes questions :

  • Pourquoi la première instruction du BIOS est-elle située au "sommet" d'une RAM de 4 Go ?
  • Que se passe-t-il si mon ordinateur ne dispose que de 1 Go de RAM ?
  • Qu'en est-il des systèmes dotés de plus de 4 Go de RAM (par exemple, 8 Go, 16 Go, etc.) ?
  • Pourquoi la pile est-elle initialisée avec une certaine valeur (dans ce cas, une valeur située à 0xFFFFFFF0) ?

J'ai lu ce sujet cet après-midi, et je ne comprends toujours pas.

63voto

LawrenceC Points 70381

0xFFFFFFF0 est l'endroit où un processeur compatible x86 commence à exécuter des instructions lorsqu'il est mis sous tension. Il s'agit d'un aspect câblé et non modifiable (sans matériel supplémentaire) du processeur, et les différents types de processeurs se comportent différemment.

Pourquoi la première instruction du BIOS se trouve-t-elle au "sommet" d'une RAM de 4 Go ?

Il est situé au "sommet" de 4 Go. espace adresse - et à la mise sous tension du BIOS ou UEFI La ROM est configurée pour répondre aux lectures de ces adresses.

Ma théorie sur le pourquoi de tout ça :

Presque tout en programmation fonctionne mieux avec des adresses contiguës. Le concepteur de l'unité centrale ne sait pas ce qu'un constructeur de système voudra faire avec l'unité centrale. C'est donc une mauvaise idée pour l'unité centrale d'exiger que les adresses situées au milieu de l'espace soient requises à des fins diverses. Il est préférable de garder cela "à l'écart", en haut ou en bas de l'espace d'adressage. Bien sûr, il faut garder à l'esprit que cette décision a été prise à l'époque du nouveau 8086, qui ne disposait pas d'un espace d'adressage de type MMU .

Dans le 8086, les vecteurs d'interruption existaient à l'emplacement mémoire 0 et plus. Les vecteurs d'interruption doivent se trouver à des adresses connues et il était souhaitable qu'ils soient dans la RAM pour des raisons de flexibilité. Pourtant, il était impossible pour le concepteur de l'unité centrale de savoir quelle quantité de RAM serait présente dans un système. Il était donc logique de commencer par 0 et de remonter (parce qu'aucun système en 1978, lorsque le 8086 a été inventé, ne disposait de 4 gigaoctets de RAM - il n'était donc pas judicieux de s'attendre à ce que la RAM soit à 0xFFFFFFF0), puis la ROM devait se trouver à la limite supérieure.

Bien sûr, à partir du 80286 au moins, les vecteurs d'interruption pouvaient être déplacés vers un emplacement de départ différent de 0, mais les CPU x86 64 bits modernes démarrent toujours en mode 8086, donc tout fonctionne encore à l'ancienne pour des raisons de compatibilité (aussi ridicule que cela puisse paraître en 2015 d'avoir encore besoin de son CPU x86 pour pouvoir exécuter DOS).

Ainsi, puisque les vecteurs d'interruption partent de 0 et vont vers le haut, la ROM devrait partir du haut et aller vers le bas.

Que se passe-t-il si mon ordinateur ne dispose que de 1 Go de RAM ?

Un processeur 32 bits possède 4 294 967 296 adresses, numérotées de 0 (0x00000000) à 4294967295 (0xFFFFFFFF). La ROM peut vivre dans certaines adresses et la RAM dans d'autres. Grâce à la MMU de l'unité centrale, il est même possible de changer d'adresse à la volée. La RAM n'est pas obligée de vivre à toutes les adresses.

Avec seulement 1 Go de RAM, certaines adresses n'auront pas de réponse lorsqu'elles seront lues ou écrites. Cela peut entraîner la lecture de données invalides lors de l'accès à ces adresses ou un blocage du système.

Qu'en est-il des systèmes dotés de plus de 4 Go de RAM (par exemple, 8 Go, 16 Go, etc.) ?

Pour rester simple : les CPU 64 bits ont plus d'adresses (ce qui est l'une des choses qui les rend 64 bits - par exemple 0x0000000000000000 à 0xFFFFFFFFFFFFFFFF) par exemple, donc la RAM supplémentaire "s'adapte". En supposant que l'unité centrale est en mode long . En attendant, la RAM est là, mais elle n'est pas adressable.

Pourquoi la pile est-elle initialisée avec une certaine valeur (dans ce cas, une valeur située à 0xFFFFFFF0) ?

Je ne peux pas trouver immédiatement quelque chose sur ce que x86 assigne au pointeur de pile à la mise sous tension, mais il devrait éventuellement être réaffecté par une routine d'initialisation de toute façon une fois que cette routine découvre combien de RAM est dans le système. (@Eric Towers dans les commentaires ci-dessous rapporte qu'il est mis à zéro à la mise sous tension).

28voto

guyumu Points 399

Il n'est pas situé au sommet de la RAM ; il est situé dans la ROM dont l'adresse est au sommet de l'espace d'adressage de la mémoire, ainsi que toute mémoire sur les cartes d'extension, comme les contrôleurs Ethernet. Elle est là pour ne pas entrer en conflit avec la RAM, du moins jusqu'à ce que vous ayez installé 4 Go. Les systèmes qui ont 4 Go ou plus de RAM peuvent faire deux choses pour résoudre le conflit. Les cartes mères bon marché ignorent simplement les parties de la RAM qui entrent en conflit avec l'emplacement de la ROM. Les cartes mères correctes remappent la RAM pour qu'elle semble avoir une adresse supérieure à 4 Go.

Je ne suis pas sûr de ce que vous demandez à propos de la pile. Elle n'est certainement pas initialisée pour être en ROM. Lorsque le processeur se réinitialise, il est initialement en "mode réel", où il agit comme le 8086 d'origine et utilise l'adressage segmenté 16 bits, ce qui lui permet d'accéder à 1 Mo de mémoire seulement. Le code du BIOS est situé au sommet de ce 1 Mo. Le BIOS choisit quelque part en RAM pour mettre en place la pile et charge et exécute le premier secteur du premier lecteur amorçable. C'est au système d'exploitation de passer en mode 32 ou 64 bits une fois qu'il a pris le contrôle et de mettre en place ses propres piles (une par tâche/thread).

18voto

Luaan Points 753

Premièrement, cela n'a rien à voir avec la RAM, vraiment. Nous parlons de espace adresse ici - même si vous n'avez que 16 Mio de mémoire, vous disposez toujours de la totalité des 32 bits de l'espace d'adressage sur un CPU 32 bits.

Cela répond déjà à votre première question : à l'époque où ce système a été conçu, les PC du monde réel étaient loin de disposer de la totalité des 4 Go de mémoire ; ils étaient plutôt de l'ordre de 1 à 16 Mio de mémoire. L'espace d'adressage était, à toutes fins utiles, libre.

Maintenant, pourquoi 0xFFFFFFF0 exactement ? Le processeur ne sait pas combien il reste du BIOS. Certains BIOS peuvent ne prendre que quelques kilo-octets, tandis que d'autres peuvent prendre des méga-octets complets de mémoire - et je ne parle même pas des différentes RAM optionnelles. Le CPU doit être câblé à une certaine adresse de départ - il n'y a pas de configuration possible du CPU. Mais il ne s'agit que d'un mappage de l'espace d'adressage - l'adresse est mappée directement dans la puce ROM du BIOS (oui, cela signifie que vous n'avez pas accès à la totalité des 4 Go de RAM à ce stade, si vous en avez autant - mais cela n'a rien de spécial, de nombreux périphériques nécessitent leur propre plage d'espace d'adressage). Sur un processeur 32 bits, cette adresse vous donne 16 octets complets pour effectuer l'initialisation de base - ce qui est suffisant pour configurer vos segments et, si nécessaire, le mode d'adressage (rappelez-vous, x86 démarre en mode réel 16 bits - l'espace d'adressage n'est pas plat) et effectuer un saut vers le fichier réel démarrer la "procédure". À ce stade, vous n'utilisez pas du tout la RAM - il s'agit uniquement de ROM mappée. En fait, la RAM n'est même pas prête à être utilisée à ce stade - c'est l'une des tâches du POST du BIOS ! Vous vous demandez peut-être comment un mode réel 16 bits peut accéder à l'adresse 0xFFFFFFF0 ? Bien sûr, il y a des segments, donc vous avez un espace d'adresse de 20 bits, mais ce n'est toujours pas suffisant. Il existe une astuce : les 12 bits de poids fort de l'adresse sont activés jusqu'à ce que vous exécutiez votre premier saut long, ce qui vous donne accès à l'espace d'adressage supérieur (tout en rejetant l'accès à tout ce qui est inférieur à 0xFFF00000 - jusqu'à ce que vous exécutiez un saut long).

Ce sont toutes ces choses qui sont le plus souvent cachées aux programmeurs (sans parler des utilisateurs) sur les systèmes d'exploitation modernes. Vous n'avez généralement pas accès à des éléments de si bas niveau - certaines choses sont déjà irrécupérables (vous ne pouvez pas changer de mode d'unité centrale bon gré mal gré), d'autres sont exclusivement gérées par le noyau du système d'exploitation.

Une vue plus agréable vient donc du codage à l'ancienne sur MS DOS. Un autre exemple typique de mémoire de périphérique directement mappée à l'espace d'adressage est l'accès direct à la mémoire vidéo. Par exemple, si vous voulez écrire du texte sur l'écran rapide, vous écrivez directement à l'adresse B800:0000 (plus le décalage - en mode texte 80x25, cela signifiait (y * 80 + x) * 2 si ma mémoire est bonne - deux octets par caractère, ligne par ligne). Si vous vouliez dessiner pixel par pixel, vous utilisiez un mode graphique et l'adresse de départ de A000:0000 (généralement, 320x200 à 8 bits par pixel). Pour faire quelque chose de performant, il fallait généralement se plonger dans les manuels des périphériques pour savoir comment y accéder directement.

Cela survit à ce jour - c'est juste caché. Sous Windows, vous pouvez voir les adresses mémoire mappées aux périphériques dans le Gestionnaire de périphériques - il suffit d'ouvrir les propriétés de quelque chose comme votre carte réseau, d'aller dans l'onglet Ressources - tous les éléments de la plage de mémoire sont des mappages de la mémoire du périphérique à votre espace d'adressage principal. Et sur 32 bits, vous verrez que la plupart de ces périphériques sont mappés au-dessus de la marque de 2 GiB (plus tard 3 GiB) - encore une fois, pour minimiser les conflits avec la mémoire utilisable par l'utilisateur, bien que ce ne soit pas vraiment un problème avec la mémoire virtuelle (les applications ne s'approchent pas de la marque de 2 GiB). réel, matériel espace d'adressage - ils ont leur propre morceau de mémoire virtualisé, qui peut être mappé à la RAM, à la ROM, aux périphériques ou au fichier de page, par exemple).

En ce qui concerne la pile, il faut comprendre que par défaut, la pile se développe à partir du haut. Donc si vous faites un push le nouveau pointeur de pile sera à 0xFFFFFEC - en d'autres termes, vous n'essayez pas d'écrire à l'adresse init du BIOS :) Ce qui signifie bien sûr que les routines d'initialisation du BIOS peuvent utiliser la pile en toute sécurité, avant de la remapper à un endroit plus utile. Dans la programmation à l'ancienne, avant que la pagination ne devienne le défaut de facto, la pile commençait généralement à la fin de la RAM, et le "débordement de la pile" se produisait lorsque vous commenciez à écraser la mémoire de votre application. La protection de la mémoire a changé beaucoup de choses, mais en général, elle maintient la compatibilité ascendante autant que possible - notez comment même le plus moderne des CPU x86-64 peut Toujours démarrer MS DOS 5 - ou comment Windows peut encore exécuter de nombreuses applications DOS qui n'ont aucune idée de la pagination.

10voto

supercat Points 1719

En plus des autres points mentionnés, il peut être utile de comprendre ce qu'est une adresse est . Bien que les nouvelles architectures compliquent les choses, historiquement, à chaque cycle de mémoire, une machine émettait l'adresse souhaitée sur 20 à 32 fils (selon l'architecture, avec quelques astuces spéciales pour noter si elle avait besoin d'une paire ou d'un groupe de quatre octets simultanément) ; diverses parties du système de mémoire examinaient l'état de ces fils et s'activaient lorsqu'elles voyaient certaines combinaisons de valeurs hautes et basses.

Si une machine avec 32 fils d'adresse n'avait besoin que d'utiliser 1 Mo de RAM et 64 Ko de ROM [ce qui est tout à fait plausible]. de ROM [tout à fait plausible pour certains contrôleurs embarqués], elle pourrait activer la RAM pour toutes les adresses où le fil d'adresse supérieur est bas et la ROM pour toutes les adresses où il est bas. pour toutes les adresses où il était haut. Les 20 fils d'adresse inférieurs seraient alors reliés à la RAM pour sélectionner un des 1 048 576 octets et les 16 fils d'adresse du bas seraient reliés à la ROM. 16 seraient reliés à la ROM également, pour sélectionner l'un des 65 536 octets. Les 11 fils d'adresse restants ne seraient tout simplement pas connectés à rien.

Sur une telle machine, les accès aux adresses 0x00100000-0x001FFFFF seraient équivalents aux accès aux adresses RAM 0x00000000-0x000FFFFF. De même, avec les adresses 0x000200000-0x0002FFFFF, ou 0x7FF00000-0x7FFFFFFFF. Les adresses supérieures à 0x80000000 lisent toutes de la ROM, avec un motif 64K se répétant dans tout l'espace.

Même si le processeur dispose d'un espace d'adressage de 4 294 967 296 octets, il y a pas besoin que le matériel reconnaisse autant d'adresses distinctes. En plaçant vecteur de réinitialisation au sommet de l'espace d'adressage est une conception qui fonctionnera bien, quelle que soit la quantité de RAM et de ROM du système. et évite de devoir décoder entièrement l'espace d'adressage.

3voto

Agguro Points 131

Ma théorie est que, parce que nous utilisons une logique négative, le chiffre 1 numérique n'est pas du tout sous tension (0 volt). Nous n'avons qu'à mettre sous tension les 4 derniers bits à l'initialisation pour que le compteur de programme (ou pointeur d'instruction) arrive à 1111 1111 1111 1111 1111 1111 1111 0000. Nous n'avons pas besoin d'adresser les 28 bits supérieurs puisque la plupart des (anciens) processeurs étaient de 16 bits et que les quarts inférieurs pouvaient être adressés par une seule puce d'adresse à l'époque. Maintenant que nous avons 64 bits avec une compatibilité avec 32 bits et 32 bits à 16 bits, le matériel peut avoir été amélioré mais la méthode reste la même. De plus, les bios ne sont pas toujours programmées en 64 bits ou 32 bits. Mon opinion est aussi que puisque les mémoires ne sont pas toujours les mêmes, le bios doit être situé au même premier segment. La façon dont nous voyons le bios adressé n'est pas la vraie adresse tout le temps. Juste un enseignement de moi ...

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X