Je sais que le BIOS charge sa première instruction à partir de 0xFFFFFFF0, mais pourquoi cette adresse spécifique? J'ai de nombreuses questions et j'espère que vous pourrez m'aider avec au moins certaines d'entre elles.
Mes questions:
- Pourquoi la première instruction du BIOS se situe-t-elle au "sommet" d'une mémoire vive de 4 Go?
- Que se passerait-il si mon ordinateur ne disposait 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 valeur (dans ce cas, une valeur située à 0xFFFFFFF0)?
J'ai lu à ce sujet cet après-midi et je ne comprends toujours pas.
Réponses:
0xFFFFFFF0
est l'endroit où un processeur compatible x86 commence à exécuter des instructions lorsqu'il est allumé. Il s’agit d’un aspect câblé, non modifiable (sans matériel supplémentaire) de la CPU et différents types de CPU se comportent différemment.Il se situe au sommet de l' espace d'adressage de 4 Go . À la mise sous tension, le BIOS ou la ROM UEFI est configuré pour répondre aux lectures de ces adresses.
Ma théorie sur pourquoi c'est:
À peu près tout dans la programmation fonctionne mieux avec des adresses contiguës. Le concepteur de la CPU ne sait pas ce qu'un constructeur de système voudra faire avec la CPU. Il est donc déconseillé pour la CPU d'exiger que les adresses situées au milieu de l'espace soient utilisées à 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, gardez à l'esprit que cette décision a été prise lorsque le 8086 était nouveau, et qu'il ne possédait pas de MMU .
Dans le 8086, des vecteurs d'interruption existaient à l'emplacement de mémoire 0 et supérieur. Les vecteurs d'interruption doivent se trouver à des adresses connues et doivent être stockés dans la RAM pour plus de flexibilité. Cependant, le concepteur de la CPU n'a pas été en mesure de connaître la quantité de RAM allouée dans un système. Donc, partir de 0 et travailler vers le haut était logique pour ceux-ci (car aucun système en 1978, lorsque le 8086 a été inventé, aurait 4 Go de RAM - attendre donc que la RAM soit à 0xFFFFFFF0 n’était pas une bonne idée), et ensuite ROM devrait être à la limite supérieure.
Bien entendu, à partir d’au moins 80286, les vecteurs d’interruption pourraient être déplacés vers un emplacement de départ différent de 0, mais les processeurs modernes 64 bits x86 démarrent toujours en mode 8086, de sorte que tout fonctionne toujours à l’ancienne pour des raisons de compatibilité (aussi ridicule que possible). comme il semble en 2015 avoir encore besoin de votre processeur x86 pour pouvoir exécuter DOS).
Ainsi, étant donné que les vecteurs d'interruption commencent à 0 et vont vers le haut, la ROM devrait partir du haut et aller vers le bas.
Une CPU 32 bits a 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. Avec la MMU du processeur, vous pouvez même l'activer à la volée. La RAM n'a pas à vivre à toutes les adresses.
Avec seulement 1 Go de RAM, certaines adresses n’auront rien à répondre lorsqu’elles seront lues ou écrites. Cela peut entraîner la lecture de données non valides lors de l'accès à de telles adresses ou le blocage du système.
Pour que cela reste un peu simple: les processeurs 64 bits ont plus d'adresses (ce qui les rend 64 bits - par exemple, 0x0000000000000000 à 0xFFFFFFFFFFFFFFFF), de sorte que la RAM supplémentaire "s'adapte". En supposant que le processeur est en mode long . Jusque-là, la RAM est là, mais pas adressable.
Je ne trouve rien immédiatement sur quoi x86 attribue le pointeur de pile à la mise sous tension, mais il devra éventuellement être réaffecté par une routine d'initialisation de toute façon une fois que cette routine aura découvert la quantité de RAM disponible dans le système. (@Eric Towers dans les commentaires ci-dessous indique qu'il est défini sur zéro lors de la mise sous tension.)
la source
0xFFFFFFF0
n'est accessible que lorsque la CPU est passée en mode 32 bits. La dernière fois que j'ai examiné le code du BIOS, le point d’entrée était0xFFFF0
:0xFFFF0
, mais en réalité, cela correspond à0xFFFFFFF0
. Je suppose que cela a été fait pour assurer la compatibilité avec le 8086 - il semble que les processeurs, tout comme les plus modernes0xFFFF0
, l' utilisent , mais les processeurs 32 bits y ont réellement accès0xFFFFFFF0
(mappés sur la ROM du BIOS).Il n'est pas situé au sommet de la RAM; il se trouve dans une ROM dont l'adresse se situe en haut de l'espace d'adressage de la mémoire, ainsi que sur les cartes d'extension, telles que les contrôleurs Ethernet. Il est là pour éviter tout conflit avec la RAM, du moins jusqu'à ce que vous ayez 4 Go installés. Les systèmes disposant de 4 Go ou plus de RAM peuvent faire deux choses pour résoudre le conflit. Les cartes mères bon marché ignorent tout simplement les parties de la RAM en conflit avec l'emplacement de la ROM. Les décents remappent cette RAM pour donner l’apparence d’une adresse supérieure à 4 Go.
Je ne suis pas sûr de ce que vous demandez à propos de la pile. Ce n'est certainement pas initialisé pour être en ROM. Lorsque la CPU se réinitialise, elle passe initialement en "mode réel", dans laquelle elle agit comme le 8086 d'origine et utilise un adressage segmenté de 16 bits, ne lui permettant que d'accéder à 1 Mo de mémoire. Le code du BIOS est situé en haut de ce 1 Mo. Le BIOS sélectionne quelque part dans la RAM pour configurer la pile, puis charge et exécute le premier secteur du premier lecteur amorçable. Il appartient au système d'exploitation de passer en mode 32 ou 64 bits une fois qu'il prend le relais et configure ses propres piles (une par tâche / thread).
la source
Tout d’abord, cela n’a vraiment rien à voir avec la RAM. Nous parlons ici d' espace d'adressage - même si vous ne disposez que de 16 Mo de mémoire, vous disposez toujours de 32 bits d'espace d'adressage sur un processeur 32 bits.
Cela répond déjà à votre première question. En fait, au moment de sa conception, les PC du monde réel n’avaient nulle part près des 4 Go de mémoire; ils étaient plus dans la gamme de 1-16 Mio de mémoire. L'espace d'adressage était, à toutes fins pratiques, gratuit.
Maintenant, pourquoi 0xFFFFFFF0 exactement? Le processeur ne sait pas quelle quantité de BIOS il y a. Certains BIOS peuvent ne prendre que quelques kilo-octets, alors que d'autres peuvent occuper tout un mégaoctet de mémoire - et je n'entre même pas dans les différentes mémoires RAM optionnelles. Le processeur doit être câblé à une adresse quelconque pour commencer - il n'y a pas de configuration pour configurer le processeur. 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 beaucoup - mais cela n’a rien de spécial, de nombreux périphériques ont besoin de leur propre plage d’adresses). Sur un processeur 32 bits, cette adresse vous donne 16 octets complets pour effectuer l’initialisation très basique - ce qui suffit pour configurer vos segments et, si nécessaire, le mode adresse (rappelez-vous,véritable démarrage "procédure". À ce stade, vous n’utilisez pas du tout de RAM, c’est juste une 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 de 16 bits peut accéder à l'adresse 0xFFFFFFF0? Bien sûr, il y a des segments, vous avez donc un espace d'adressage de 20 bits, mais cela ne suffit toujours pas. Eh bien, il y a une astuce: les 12 bits de poids fort de l'adresse sont définis jusqu'à ce que vous exécutiez votre premier saut en longueur, ce qui vous donne accès à l'espace d'adressage en hauteur (tout en refusant l'accès à une valeur inférieure à 0xFFF00000 - jusqu'à ce que vous exécutiez un saut en longueur) .
Tous ces éléments sont essentiellement masqués par les programmeurs (sans parler des utilisateurs) sur les systèmes d'exploitation modernes. Vous n’avez généralement accès à aucun niveau aussi bas - certaines choses sont déjà irrécupérables (vous ne pouvez pas changer de mode de processeur à tout moment), d’autres sont gérées exclusivement par le noyau du système d’exploitation.
Une vue plus agréable provient donc du codage old-school sous MS DOS. Un autre exemple typique de mémoire de périphérique mappée directement sur un espace d'adressage est l'accès direct à la mémoire vidéo. Par exemple, si vous voulez écrire rapidement du texte sur l’affichage, vous écrivez directement dans adresse
B800:0000
(plus décalage - en mode texte 80x25, cela signifie que(y * 80 + x) * 2
si ma mémoire est fidèle - 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 deA000:0000
(typiquement, 320x200 à 8 bits par pixel). Faire quelque chose de très performant signifiait généralement plonger dans les manuels des appareils pour savoir comment y accéder directement.Cela survit à ce jour - c'est juste caché. Sous Windows, vous pouvez voir les adresses de mémoire mappées aux périphériques dans le Gestionnaire de périphériques. Ouvrez simplement les propriétés de votre carte réseau, allez à l'onglet Ressources. Tous les éléments de la plage de mémoire sont des mappages de la mémoire du périphérique vers 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 2 GiB (plus tard 3 GiB) - encore une fois, pour réduire les conflits avec la mémoire utilisable par l'utilisateur, bien que cela ne soit pas vraiment un problème avec la mémoire virtuelle ( les applications ne s'approchent pas de l' espace d'adressage matériel réel - elles ont leur propre bloc de mémoire virtualisé, qui peut être mappé sur la RAM, la ROM, les périphériques ou le fichier de page, par exemple).
Pour ce qui est de la pile, cela devrait aider à comprendre que, par défaut, la pile se développe à partir du haut. Donc, si vous faites un
push
, le nouveau pointeur de pile sera0xFFFFFEC
: autrement dit, vous n'essayez pas d'écrire sur l'adresse d'initialisation du BIOS :) Cela signifie bien sûr que les routines d'initialisation du BIOS peuvent utiliser la pile en toute sécurité, avant de la remapper. quelque part plus utile. Dans la programmation traditionnelle, avant que la pagination ne devienne la valeur par défaut, la pile commençait généralement à la fin de la mémoire vive et un "débordement de pile" se produisait lorsque vous commenciez à écraser la mémoire de votre application. La protection de la mémoire a beaucoup changé, mais en général, elle maintient la compatibilité avec les versions antérieures autant que possible. Notez que même le processeur x86-64 le plus moderne peut toujours démarrer MS DOS 5. - ou comment Windows peut toujours exécuter de nombreuses applications DOS qui n'ont aucune idée de la pagination.la source
0xFFFFFFEC
serait mappé). Cela signifie non seulement nonpush
mais par exemple noncall
plus. Ceux-ci doivent attendre que la RAM soit prête.En plus des autres points mentionnés, il peut être utile de comprendre ce qu'est une adresse est . Tandis que les architectures récentes compliquent les choses, une machine publiait à chaque cycle de mémoire l’adresse désirée sur 20 à 32 fils (selon l’architecture, avec quelques astuces spéciales pour noter si elle nécessitait une paire ou quatre octets simultanément); diverses parties du système de mémoire examineraient l'état de ces fils et s'activeraient lorsqu'elles verraient certaines combinaisons de valeurs hautes et basses.
Si une machine dotée de 32 câbles d’adresse ne devait utiliser que 1 Mo de RAM et 64 Ko de ROM [assez plausible pour certains contrôleurs intégrés], elle pourrait activer la RAM pour toutes les adresses où le fil d’adresse supérieur était bas et la ROM pour toutes les adresses où il se trouvait. haute. Les 20 fils d’adresse du bas seraient alors liés à la RAM pour sélectionner l’un des 1 048 576 octets et les 16 derniers seraient également connectés à la ROM, pour choisir l’un des 65 536 octets. Les 11 fils d’adresse restants ne seraient tout simplement pas connectés à quoi que ce soit.
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 liraient toutes en ROM, avec un motif de 64 Ko répété dans tout l'espace.
Bien que le processeur dispose d'un espace d'adressage de 4 294 967 296 octets, il n'est pas nécessaire que le matériel reconnaisse autant d'adresses différentes. Placer le vecteur de réinitialisation près du haut de l'espace d'adressage est une conception qui fonctionnera bien quelle que soit la quantité de mémoire RAM et de ROM dont dispose le système et évite la nécessité de décoder complètement l'espace d'adressage.
la source
Mon cas est parce que nous utilisons la logique négative, le numérique (1) n’existe aucune tension (0 volts). Il suffit de mettre les 4 derniers bits sous tension lors de l’initialisation pour que le compteur de programme (ou le pointeur d’instruction) se mette à 1111 1111 1111 1111 1111 1111 1111 0000. Nous n'avons pas à nous adresser aux 28 bits supérieurs, car la plupart des processeurs (anciens) avaient 16 bits et les nœuds inférieurs pouvaient être adressés par une seule puce d'adresse auparavant. Maintenant que nous avons 64 bits avec une compatibilité de 32 bits et de 32 bits à 16 bits, la méthode matérielle a été améliorée mais la méthode est restée inchangée. De plus, les bioses ne sont pas toujours programmées sur 64 ou 32 bits. Mon opinion est également puisque les souvenirs ne sont pas toujours les mêmes, le bios doit être situé sur le même segment. La façon dont nous abordons le bios n’est pas la vraie adresse tout le temps. Juste un appris de moi ...
la source
Lors de la réinitialisation, un processeur compatible 8088/8086 exécute les instructions à 0FFFF0, soit 16 octets sous la limite de 1 mégaoctet. normalement la ROM à cet emplacement (dans les implémentations de PC) serait le BIOS, donc à la fin de la ROM du BIOS, il y a un saut au début de la ROM du BIOS.
montré ici: vecteur de départ et signature 'date' derrière, BIOS 5150 d'IBM 5150 PC 8KB date du: 19/10/1981
notez que l'adressage est d'une valeur de 8KB $ 2000 rom, qui place l'adresse de départ (le JMP absolu, à n'importe quel autre emplacement, dans ce cas dans la même quantité de 8KB, bien que ce ne soit pas l'adresse la plus basse possible): $ FFFF: Segmenté à 0 $ ou linéaire FFFF0.
en ce qui concerne la compatibilité: si un processeur "futur" ou actuel "s'attend" à ce qu'il ait beaucoup plus de F devant l'adresse, cela n'a pas d'importance. pour la compatibilité des processeurs les plus récents dans les systèmes plus anciens, les lignes d’adresse supplémentaires ne sont pas connectées et, par conséquent, les données sur le bus de données sont exactement les mêmes. tant que les bits les moins significatifs restent FFFF0.
(Dans un système avec seulement 1 Mo de RAM et la ROM située à la fin de celui-ci, rien de plus, il sera heureux de penser qu'il parle à l'adresse la plus élevée tout en obtenant exactement les mêmes données, car ces implémentations n'ont jamais entendu parler de lignes d'adresse supérieures à A19)
notez que le monde n’est pas que des "ordinateurs" ... l’ordinateur IBM était un "accident", ces processeurs n’ont jamais été conçus spécifiquement pour les "ordinateurs" et constituent bien plus que de simples ordinateurs (tels que systèmes d'armes, etc.). Les modes protégés 32 et 64 bits ne sont généralement pas souhaités. (Le mode virtuel 8086 est beaucoup plus intéressant en tant que raison de choisir une version plus récente (386+) par exemple). par conséquent, la «compatibilité ascendante» comporte bien plus que la simple exécution.
la source
La carte mère veille à ce que l'instruction du vecteur de réinitialisation corresponde à un saut vers l'emplacement de mémoire mappé sur le point d'entrée du BIOS. Ce saut efface implicitement l'adresse de base cachée présente à la mise sous tension. Grâce à la carte mémoire conservée par le chipset, tous les emplacements de mémoire disposent du contenu adéquat requis par la CPU. Ils sont tous mappés sur une mémoire flash contenant le BIOS car, à ce stade, les modules de RAM ont une merde aléatoire.
la source