|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Bonjour j'aimerais la réponse à certaines questions que je me poses. Je sais que mes questions pourraient en irrités quelqu'uns, en ce sens, svp soyez courtois face a mon manque de cultures! ;p Bref, voici mes questions :
Pour un intel 64bit 1. Quel est le moyen de connaitre les informations sur les peripheriques et "features" de mon motherboard? CPUID? Dautres methodes? 2. Y a t il moyen de communiquer avec les peripheriques disponibles? (Mode reel, protegee?) 3. Dans le cas de la conception d'un micronoyau en C, quel serait la méthode appropriée pour acceder aux peripheriques disponibles? Merci de votre aide dédié a ma comprehesion de ces connaissances |
|
|
00
|
|
|
#2 |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Bonjour,
Même si les processeurs Intel x86, spécialement en 64 bits, sont utilisés à 99 % dans les PC, il n'en reste pas moins qu'un micro-processeur est en soi un produit distinct et en principe indépendant de l'environnement dans lequel il tourne. Ceci veut dire qu'en assembleur, tu vas avoir à ta disposition d'instructions dédiées pour obtenir des informations sur le micro-processeur lui-même (par exemple CPUID, ainsi que les flags, les registres CR0, CR1, etc.) et pour le manipuler, mais pas pour interroger directement ce qui l'entoure sur un point précis. À dire vrai, l'exploitation entière de ton ordinateur va se faire en lisant certaines adresses en mémoire et en écrivant à d'autres. Y compris la gestion des périphériques. Les micro-processeurs Intel font toutefois un distingo entre l'adressage normal de la mémoire et l'exploitation des périphériques, lequels s'adressent de manière indirecte avec « IN » et « OUT » mais au final, électroniquement, les accès se font à travers le même bus modulo une ligne spéciale indiquant quel genre de transfert on souhaite effectuer. Concrètement, tu peux communiquer avec tous tes périphériques en assembleur, à commencer par les périphériques « historiques », principalement émulés aujourd'hui par le chipset, et qui ont un emplacement fixe dans le plan d'adressage. Cela concerne notamment le clavier, le port parallèle, les ports série, la gestion du port PS/2 également, mais aussi le timer, qui servait entre autre à générer des tonalités vers le buzzer du PC avant qu'il commence à être doté d'une carte son. Pour le reste, il y a d'un côté des technologies comme http://en.wikipedia.org/wiki/Desktop...ment_Interface ou SMBus, basées qui permettent justement de recenser les différents composants sur une même carte. Pour les autres périphériques connectés au bus PCI, soit branchés sur les slots, soit directement intégrés à la carte-mère mais utilisant PCI quand même, ceux-ci n'ont plus d'adresse fixe assignée par défaut comme du temps du bus ISA. Il faut procéder à une énumération des périphériques du bus PCI (comme avec l'USB) puis mapper celui-ci qui nous intéresse en mémoire ou sur les ports I/O et, de là, l'exploiter à notre convenance. Cette énumération comme le reste de la gestion du bus PCI se fait à travers des ports I/O fixes s'étendant de 0xCF8 à 0xCFF. Enfin, dans tous les cas, si tu pars de zéro, soit tu utilises les interruptions BIOS déjà à disposition pour gérer ces périphériques, soit tu les pilotes directement (spécialement si tu es en mode protégé et que tu ne peux utiliser le BIOS). Mais dans ce cas, tu pourras utiliser indifféremment les anciens périphériques standard sur toutes les machines (notamment la carte graphique jusqu'aux modes VGA, mais pas plus haut). Par contre, pour les autres, il te faudra écrire un programme spécial pour chaque type de périphérique. C'est le cas notamment si tu veux utiliser ta carte réseau, par exemple. En fait, il n'y a pas de secret : si tu écris un mini-OS, il faudra que tu écrives les pilotes qui l'accompagnent, ce qui n'est pas une mince affaire. J'ai passé le mois dernier à faire exactement la même chose : un nano-OS qui démarre en DHCP/PXE via le réseau sur une machine sans disque et qui, de là, met tout en place jusqu'à proposer une mini-console, soit capable de télécharger le reste du système via ma carte réseau, puis accède au bus USB via le bus PCI et qui, en dernier lieu, essaie d'atteindre mon système audio USB (5.1 indépendant avec un caisson de basse). Je n'ai pas encore fait la partie réseau, ni l'USB, ni l'audio. Le reste fonctionne. Je te conseille de visiter http://wiki.osdev.org/ . C'est un wiki consacré à cette activité en particulier et qui, donc, réunit sur un même portail les ressources dont tu as besoin. |
|
|
10
|
|
|
#3 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Mon dieu merci beaucoup obsidian, ça cest de linformation riche en detail!
CPUID et flags : infos processeur et feature mini-nano-micro-OS: soit interruption bios mais comme sa jcrois que tu (developpeur) reste limité a utiliser un mode precis du processeur (max 2Mo adressage). Soit par ecriture de pilote et mappage en memoire ou sur les I/O. Tres bien, mais toute ces informations comme ecriture lecture initialisation dun peripherique (ex carte reseau) a quel endroit ce trouve telle afin de mapper et decrire des methodes avec les bonnes commandes? |
|
|
00
|
|
|
#4 | |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
C'est un poil plus subtil. Le 8086 est apparu en 1978, il y a trente-quatre ans, donc. Et toute la gamme x86 jusqu'aux Core actuels est une évolution progressive à partir de ce modèle, sachant qu'Intel en a également produit d'autres et qu'il est loin d'être le seul fabricant de micro-processeurs.
Le registre « flags » est à la base quelque chose qui existe sur tous les micro-processeurs. On l'appelait « CC » (Code Condition) sur les 68xx de Motorola, par exemple. C'est lui qui est chargé de refléter l'état du résultat de la dernière opération arithmétique et logique et il est nécessaire, entre autres, pour effectuer des sauts conditionnels. Intel, en faisant évoluer ses processeurs tout en conservant une compatibilité ascendante jusqu'au premier jour et en profitant d'une technologie progressante et qui permettait à terme de faire facilement ce qui aurait jadis posé des problèmes technologiques, a fini par ajouter des informations dans ces fameux flags (ce qui n'était pas très propre) puis par ajouter des registres dédiés. « CPUID », en revanche, n'est apparu qu'avec le Pentium et les derniers 486, soit quinze ans après la naissance du premier modèle. C'est une instruction qui est propre aux Intel, même si d'autres fabricants peuvent proposer quelque chose de similaire, c'est loin d'être une généralité. Ça veut dire aussi que tu peux l'utiliser dès que tu sais qu'elle est disponible, mais que cela plantera si tu l'appelles sur un processeur plus ancien. C'est pourquoi Intel consacre un bit des flags à l'indication de disponibilité de cette instruction. C'est aussi pour cela que ce n'est pas une très bonne idée de courir tous les lièvres à la fois : les processeurs pour PC de dernière génération sont trop sophistiqués. C'est sympa à l'usage, mais c'est compliqué pour rien et cela donne une vision biaisée de l'assembleur si on commence directement par les plus gros et qu'on ne voit que cela. Ensuite, par définition, quand tu écris un nano-OS, c'est toi qui doit faire tout le travail. Ça demande donc une certaine expertise. C'est pas forcément difficile avec la doc, mais ce n'est pas non plus une tâche de débutant. Et surtout : c'est long ! Citation:
Dans les années 1990, Michael Tischer avait sorti la « Bible PC », un ouvrage gros comme un dictionnaire et qui a été réédité six ou sept fois, jusqu'à Windows 95. Après, je n'ai rien vu de tel. Connaître les technologies populaires tient donc de la veille technologique. Mais surtout, ce qui fait qu'un PC reste un PC est que chacune d'elles est accessible via la précédente. Par exemple, les périphériques capables de s'annoncer via DMI le font à travers une interface, laquelle est elle-même et en principe mappée sur le bus PCI. Tous les autres périphériques « normaux », qu'ils soient intégrées à ta carte-mère ou sur un slot, communiquent aujourd'hui à travers le bus PCI (les bus ISA, et temporairement VLB, ont complètement disparu). Le bus PCI lui-même a beaucoup évolué : tout le monde travaille aujourd'hui avec du PCI-Express, mais c'est le même principe et surtout, c'est compatible. C'est qui nous amène à ta question : pour utiliser correctement un périphérique une fois dûment mappé via le bus PCI. Il faut le « piloter » et donc écrire son pilote. Pour cela, il te faut les « spécifications » du périphérique concerné et cela, seul son constructeur peut te les fournir (initialement). S'il est conciliant, tu les trouveras sur son site, mais ça veut quand même dire qu'il faut écrire un pilote particulier par périphérique ou, au moins, par famille de périphérique. C'est pour cela que tu installes toujours les « drivers » d'un nouvel équipement sous Windows. Tout gérer représente donc une quantité considérable de travail. Or, et c'est bien là le problème, sous Windows, ce n'est pas Microsoft qui écrit la totalité des pilotes mais les constructeurs eux-mêmes, qui le fournissent s'ils veulent vendre leur produit. Sous Linux, par exemple, à quelques exceptions près (les pilotes nVidia par exemple) on n'installe pratiquement jamais les pilotes car c'est la communauté qui les développe, et gratuitement en plus ! Intégrés au noyau, ils sont automatiquement détectés et chargés. Et ça semble fonctionner tout seul. Mais c'est aussi pour cela que les produits trop récents ne sont pas immédiatement fonctionnels, sauf quand ils respectent à la base une norme déjà existante. D'autre part, beaucoup de constructeurs, Canon par exemple, se font fortement prier pour ouvrir leurs spécifications. Gagner gratuitement des parts de marché en laissant la communauté travailler pour eux ne semble pas les séduire et on a eu beaucoup de déboire avec des produits parfois aussi simples qu'une imprimante à jet d'encre. Dans ce cas, il faut faire du reverse engineering dans les pays où c'est autorisé pour pouvoir simplement utiliser l'appareil qu'on a légalement acheté. En France, cette pratique est autorisée sous certaines conditions. Aujourd'hui, les bus PCI et USB intègrent un système d'identifiants fabricant/produit (vendor:device) qui te permet d'identifier à coup sûr un produit particulier et même sa sous-version. Il est donc très facile de le détecter et de charger le bon pilote en conséquence. Par contre, à l'époque du bus ISA, chaque constructeur s'allouait plus ou moins arbitrairement un bout de la plage adressable. Par exemple, les cartes Sound Blaster étaient typiquement en 0x220 et suivants, si on ne l'avait pas déplacée ailleurs à l'aide de cavaliers jumpers. Du coup, pour sonder sa présence, il fallait faire du polling prudemment à cette adresse et vérifier si les résultats étaient cohérents. Tu trouveras sur OSDev la plupart des spécifications des périphériques historiques que l'on trouve dans un PC. Pour le reste, la prochaine étape consistera à initialiser correctement le bus PCI. |
|
|
|
20
|
|
|
#5 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Merci encore et toujours obsidian!
|
|
|
00
|
|
|
#6 | |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
Avec quel système d'exploitation travailles-tu ? Si tu n'as pas encore essayé Linux, je te suggère d'aller récupérer et graver l'ISO d'une distribution en Live CD telle que Knoppix. Ceci te permettra de démarrer sur le CD et d'obtenir un système utilisable sans avoir à installer quoi que ce soit sur ta machine cible, ce qui est assez remarquable ! Si tu as une clé USB inutilisée, tu peux également la consacrer à cela. Une fois que tu as démarré, essaie les commandes « dmidecode », « lspci » et « lsusb » qui, à elles trois, te donneront une liste déjà très exhaustive de ce que tu trouves dans ta machine. De là, tu pourras mettre tranquillement le pied à l'étrier si l'activité t'intéresse. |
|
|
|
20
|
|
|
#7 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Oui je sais, je ne suis pas le moindrement decourager! Au contraire, je cherchais juste une lanterne pour meclairer dans ces connaissances! Et oui, jconnais linux, fais maintenant 20% de ma vie que je consacre a cet OS de predilection! :-) (avant seulement lusuel windows...)
Dsl, jai un autre question.... ok jai un core i7. Prenons lordi avec seul le bios/uefi... estce que le processeur apres demarage et test/initialisation par bios/uefi est en mode Protègé ou IA-32e ou reel? Apres tout depandamment du mode jimagine quil faudra que jactive des features comme Pagination avant de mappé les I/O en memoire? |
|
|
00
|
|
|
#8 | ||
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
Pour UEFI, c'est un peu plus subtil. Je n'ai pas eu le temps de parcourir ses spécifications en détail mais ce qu'il faut retenir est qu'il est désormais écrit en C, c'est-à-dire que que ses services se font à travers d'appels de fonctions et plus d'interruptions assembleur fixes, et qu'il est également conçu pour être indépendant de la plateforme utilisée (parce que son interface ne dépend pas d'une architecture donnée). Cela dit, UEFI utilise un flat mode et travaille fondamentalement en mode protégé sans pagination. UEFI te permet de démarrer un O.S. en mode réel 16 bits si tu le souhaites, mais ses services ne seront pas utilisables par cet O.S. ou les programmes qu'il fait fonctionner. Citation:
Après cela, la pagination et le mapping de périphériques sont deux mécanismes qui permettent d'exploiter le plan adressable. La première sert principalement à mettre en place la mémoire virtuelle, le second sert à rendre visible un périphérique donné. |
||
|
|
20
|
|
|
#9 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Bon, très bien, après plusieurs lectures et quelques tests, je recherche une conclusion.
Prenons, par exemple, le i7 et le bios sans OS sur un quelconque support ou périphérique. J'appuie sur le bouton d'alimentation de UC. Le BIOS effectue ses routines d'initialisation des composantes, recherche un secteur d'amorçage et lui passe le contrôle. S'il ne trouve rien, affiche un message d'erreur ("no boot sector found, please press a key to reboot"). Par contre, s'il trouve un secteur d'amorçage, le charge en mémoire et lui donne le contrôle. Très bien. Donc, selon ce que vous avez dit, principalement, sauf sur exception, le BIOS est en mode réel 16bits, alors, lorsqu'il passe le contrôle à ce "secteur d'amorçage" celui-ci hérite donc des caractéristiques du BIOS ("mode réel 16bits", ainsi que tous les registres configurés par le BIOS). Est-ce bien cela? Dans ce cas, cela signifie que le "boot sector" doit être écrit en 16bit, passe le contrôle a un autre secteur (car boot sector limité a 512octets). Ce nouveau secteur doit donc trouver la mémoire installée et totale (int 0x15 je crois), facultativement la mettre en ordre, créer et charger une GDT, créer et charger une IDT (est-ce que les descripteurs peuvent pointer sur les interruptions bios?), positionner le pointeur d'adresse sur la première adresse utilisable de la GDT, analyser les bus PCI et mettre les périphériques trouvés dans la GDT et finalement sauté à la première adresse utilisable. C'est donc je que je crois avoir compris. Sinon, avant de sauter à la première adresse utilisable : charger un noyau dans les adresses utilisables et sauter dans son adresse de démarrage (ex : main()). Est-ce que je suis dans "l'champ" ou c'est réaliste comme compréhension ? |
|
|
00
|
|
|
#10 | ||||||
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Bonsoir
Citation:
Citation:
Toujours est-il qu'en pratique, le premier secteur est pour ainsi dire toujours utilisé pour charger en une fois une suite de secteurs consécutives situés à un endroit arbitraire. Ça permet de mettre en place directement un mini-système qui va faire les initialisations nécessaires et procéder au chargement du reste du système. Il se peut même que ce bootstrap charge directement le système entier dans le cas de nano-OS écrits par des amateurs éclairés comme on en trouve sur ce forum. Citation:
En fait, bien avant le mode protégé, l'ACPI, le bus PCI, etc. le plan mémoire des ordinateurs 8 et 16 bits était généralement fixé à l'avance sur le méga-octet adressable par les 20 bits du bus du 8086, 640 Ko étaient réservés à la RAM. Les tout premiers PC étaient livrés avec 64Ko de mémoire, puis 256, puis pendant longtemps 512 Ko, et enfin 640 Ko bien remplis, avant de passer à la mémoire étendue avec le 1er Mo. Mon 486DX33 de 1992 était livré avec 4Mo de RAM, il y en a 1024 fois plus sur les machines actuelles. :-) Ceci pour dire que la mémoire visible en mode réel aujourd'hui fait forcément 640 Ko et se trouve toujours au même endroit. Ceci te laisse largement la place de passer en mode protégé et de faire le bilan des plages mémoire disponibles ensuite. Citation:
Les descripteurs IDT ne peuvent pas pointer les interruptions du BIOS, car ces routines sont écrites en mode réel. La gestion des segments est complètement différentes et même si le code pouvait aller à son terme, lesdites interruptions sont conçues pour aller directement manipuler le matériel, chose qui ne sera plus possible en environnement multitâche même si en donnant les pleins pouvoirs au segment des descripteurs d'interruption. Cette question est un grand classique à laquelle la réponse est « tu vas bel et bien devoir tout réécrire ». Ça reste très intéressant en soi, et tu n'es heureusement pas obligé d'avoir tout réécrit pour obtenir un nano-système qui fonctionne. Citation:
Le niveau 0 est le privilège le plus fort, le niveau 3 le plus faible. Typiquement, le noyau de ton système d'exploitation sera en ring 0 et tes applications en ring 3. Cette GDT est une particularité du x86 et les périphériques embarqués dans un ordinateur sont complètement indépendants du micro-processeur qui les pilote. Une fois que tu as défini l'emplacement de ces segments en mémoire, il te suffit de charger leur « numéro », ou plus particulièrement un offset en octets par rapport au début de cette table, dans les registres de segments que tu utilisais déjà en mode réel pour l'adressage se fasse automatiquement par rapport au début du segment choisi. Citation:
|
||||||
|
|
20
|
|
|
#11 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
haaaaaa :-) tiguidou alors! le seul bout encore flou est ici : tu as dis que la mémoire total était adresser de façon linéaire et que donc, dans cette linéarité, on y trouvait les périphériques PCI. Cest pour ça que je disais de les "trouver" et les ajoutés a la GDT et donc, avec un certain ring (0-3). Mais, tu dis que les x86 font la différence entre mémoire et périphérique........ donc mémoire = ensemble registre et mém. volatile, accessible par instructions. périphériques : par instruction in et out seulement, car directement ou arbitrairement programmé sur les pin I/O?
|
|
|
00
|
|
|
#12 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
- ooooohh....... et aussi utilisé int 0x15, e820 au début pour justement trouvé les 640 ko utilisable et évité d'écrire par dessu le bios. Ou est-ce juste impossible de réécrire pardessus?
- Et pour la réécriture de tout (je n'en peu plus de devoir attendre :-)), la technique qui me vient a l'esprit est de faire tout plein de test en mode réel, et donc réadapter a mon mode protéger...... ou bien il y a des standards de communication pour tout les périphériques..... car c'est bien beau avoir un nano-OS, mais par la suite il ne servira a rien s'il ne peut enregistrer sur un support ou exploiter quoi que ce soit. |
|
|
00
|
|
|
#13 | |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
Effectivement, il faudra mapper les périphériques PCI quelque part dans le plan adressable et déclarer un segment dessus pour qu'ils soient visibles. Par contre, il est assez rare que l'on déclare un segment par périphérique. À la place, on déclare plutôt un grand segment de travail et on mappe tout dedans. Ceci n'est bien sûr valable que pour les périphériques réputés utiliser une plage mémoire. Ça ne concerne pas les I/O. La mémoire conventionnelle, les 640 premiers Ko donc, s'étend forcément de 0000:0000 à A000:0000-1. Tu n'as pas besoin de la chercher. Par contre, il faut faire attention à ce que le BIOS y met au départ, à commencer par les vecteurs d'interruption en mode réel, de 0000:0000 à 0000:0400. |
|
|
|
20
|
|
|
#14 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
des cases mémoires de 1octets et des adresses de 2octets?
|
|
|
00
|
|
|
#15 |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Comment ça ?
|
|
|
00
|
|
|
#16 |
|
Membre expérimenté
![]() ![]() François conception mécanique Inscription : janvier 2005 Messages : 330 ![]() |
Juste une petite précision, pas bien utile, mais bon, comme j'ai pas mal
joué avec le MBR dans ma jeunesse, le BIOS ne contrôle que les 2 derniers octets pour lancer l’exécutions du secteur. C'est pour cela que le début du secteur est un jmp vers le début du code, après les données des 4 partitions primaires. Du coup, si on veut, on peut faire un secteur d'amorce avec 510 octets de code |
|
|
20
|
|
|
#17 | |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
|
|
|
|
10
|
|
|
#18 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
finalement je recherche une, je l'espère xD, dernière précision. en mode 16bits, 2^20 octets son adressable, donc 1048576 octets (1 Mo). Comment fonctionne la notation segment:offset? est-ce que la valeur d'une adresse est en hexadécimale ou en décimale ou même octale(me surprendrais pour celle-ci) ou peu importe tandis qu'on respecte la limite d'adressage? Je cherche a comprendre, est-ce que le segment de segment:offset représente une adresse de base sur laquelle on applique un décalage de X offset et que rendu a ce décalage nous trouvons la case mémoire qui doit être de 2 octets (16 bits), donc soit une case code pour une instruction de 16 bits, soit une case donnée de 16bits ou bien une instruction 8bits et une donnée 8bits. Car dans l'exemple des 640 premiers Ko a la limite de A000:0000 -1, moi 0xA000 = 40960. donc +- 40Ko et non 640Ko. Car en hexadécimale, dans ma "logique d'incompréhension", 1048576 octets partent de 0000:0000 à 000F:FFFF donc FFFFF = 20bits bien remplis. Récapitulons, les cases mémoires on quel grandeur (1 octets, 2 octets, 4 octets)? et dans mon exemple d'adressage, est-ce que je me suis trompé? Car voilà 3ans, mes profs d'infos, pas tous, mais certains, disaient que l'espace la plus petite dans la mémoire était de 4 octets, c'est toujours d'actualité ou? Car 4 octets, moi ça sonne mode 32 bits, donc mode 16 bits, des cases de 2 octets? Car si j'en arrive à une conclusion suivant se raisonnement d'un adressage à la 2^20. 1048576 adresses disponibles de 2 octets, donc une mémoire totale utilisable(lecture/écriture) de 2Mo pour les CPU les plus ressens de 16bits de l'époque xD.
|
|
|
00
|
|
|
#19 |
|
Candidat au titre de Membre du Club
![]() J D Électro-mécano-informaticien à ses heures Inscription : août 2010 Messages : 75 ![]() |
Et qui, ma foi, 2Mo, en mode 16bits avec des programmes en ASM, devait être largement suffisant pour les besoins de l'époque. J'ai un choc lol, car un OS total en ASM doit rien prendre quand tu as 8 589 934 592 octets de dispo.
|
|
|
00
|
|
|
#20 | |||||||
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
Donc, en mode réel, le registre de segment est décalé de 4 bits vers la gauche (soit exactement un chiffre hexadécimal) par rapport à l'offset. Il « pèse » donc seize fois plus que le registre d'offset. Ces deux registres sont additionnés électroniquement pour former l'adresse physique qui va être directement envoyée sur les broches électriques du bus d'adresse (au moins sur les vieux modèles). Donc, les couples 0010:0000, 0000:0100, 0001:00F0, 0005:00A0 ou 000F:0010, pour ne citer qu'eux, correspondent tous à la même adresse physique 00100. Ça s'explique par le fait que lorsque le 8086 est apparu, les micro-processeurs 16 bits étaient déjà au point. Tous ses registres internes, y compris le pointeur de programme « IP » qui pointe en mémoire l'adresse de la prochaine instruction à exécuter étaient larges de seize bits ainsi que toute la circuiterie interne permettant de véhiculer leur contenu entre eux et vers la mémoire. Un programme est donc « habitué » à voir une zone mémoire de 64 Ko. Même les micro-processeurs 8 bits des années 80 (Z80, 6809…) disposaient quand même de registres d'index de 16 bits (car un plan mémoire de 256 octets, c'est vraiment trop serré). Pour étendre l'espace utilisable, on utilisait couramment de la mémoire paginée telle que l'EMS sur PC : en gros des pages de mémoire de taille fixe et occupant toutes la même place et donc on choisissait la page active à un moment donné à l'aide d'un sélecteur, un peu comme quand on ouvre un tiroir d'une grande armoire. Or, pour exploiter sur un tel matériel un bus d'adresse de 20 bits, il n'était pas concevable de développer des registres de 20 bits eux-aussi : c'est toute l'architecture qu'il aurait fallu adapter, ne serait-ce que pour pouvoir les charger, et faire des calculs dessus. En outre, « 20 » n'est pas une puissance de 2. Doter le 8086 de tels registres serait revenu à concevoir un nouveau micro-processeur depuis zéro. Par contre, il était très facile d'utiliser deux registres de 16 bits chacun. Rajouter un tel registre à ceux déjà existants ne posait pas de difficulté particulière. Et plutôt que simplement concaténer ces registres et n'utiliser que les 4 bits de poids faible du registre de segment, il était beaucoup plus astucieux de les associer comme décrit ci-dessus. D'abord, parce que si on souhaitait simplement ajouter quatre bits de manière linéaire, il suffisait d'utiliser les quatre bits de poids fort du registre de segment et non de poids faible. Ensuite — et surtout — parce que cela garantit la compatibilité ascendante en permettant de placer la zone visible de 64 Ko dont les programmeurs avaient déjà l'habitude n'importe où en mémoire avec une granularité de 16 octets. C'est aussi la raison pour laquelle il est plus difficile de manipuler un registre de segment que tout autre registre : les manières de les charger ou les lire sont volontairement limités pour économiser les codes-opérations et parce qu'en général, on l'initialise une fois pour toute en début de programme pour ne plus s'en soucier ensuite. C'est relativement simple et c'est évident une fois qu'on le sait. On comprend également que c'est une solution qui vient naturellement à l'esprit à toute personne confrontée à ce problème lors de la conception du micro-processeur. Toutefois, les « fameux segments » sont une question récurrente qui a causé bien des maux de tête aux étudiants et aux « amateurs avertis » dont je faisais partie à la fin des années 1980, surtout à une époque où Internet n'existait pas en France, en tout cas pas sous sa forme actuelle. En mode protégé, maintenant, cela fonctionne un peu différemment : ce n'est plus directement le contenu du registre qui sert à calculer l'adresse mémoire physique, il ne s'agit que d'un index dans un table définie en mémoire et dans laquelle sont décrits différentes plages, dont la longueur et l'emplacement sont arbitraires. Il est même possible de déclarer deux plages strictement identiques. Le fonctionnement est donc différent mais on a conservé les registres existants pour les utiliser à cette fin, ce qui est le plus intelligent à tous les niveaux puisque la technique « mode réel » n'est plus utilisable en mode protégé et que, sémantiquement, il s'agit toujours de la même chose : définir des plages de mémoire distinctes pour le code et les données, d'une part, et pour les différents programmes cohabitant sur la même machine en général. Citation:
L'hexadécimal est utilisé car un chiffre hexadécimal correspond exactement à quatre bits. Il est donc très facile de convertir l'un vers l'autre et réciproquement car il suffit de convertir un à un chaque chiffre indépendamment des autres, sans avoir à faire de divisions successives. L'octal servait à la même chose mais a été abandonné d'abord parce qu'il codait moins d'informations que le décimal et parce que chaque chiffre correspondait à trois bits, ce qui n'était vraiment pas pratique : ce n'est multiple ni de 8 bits (les octets), ni de 7 (courant sur les transmissions ASCII de l'époque), ni de 16. C'était pénible parce que pour représenter un octet, par exemple, il fallait trois caractères, ce qui permettait de représenter 512 combinaisons différentes et non 256. Il était donc pratiquement toujours possible d'écrire des valeurs invalides en octal avec les formats de données usuels, valeurs qu'il fallait alors contrôler et traiter, chose qui n'arrivait pour ainsi dire jamais en hexadécimal. Les seuls intérêts de l'octal résidait dans le fait qu'on se cantonnait aux chiffres que l'on connaissait déjà et à une suite de symboles consécutives dans la table ASCII. L'hexadécimal étant beaucoup plus pratique à l'usage, il a fini par s'imposer. Citation:
Citation:
Citation:
Citation:
Citation:
Un simple fichier icône pèse aujourd'hui 2 à 3 fois plus lourd. |
|||||||
|
|
20
|
Copyright © 2000-2013 - www.developpez.com