1 points par GN⁺ 2 시간 전 | 1 commentaires | Partager sur WhatsApp
  • La ROM de microcode du 80386 contient 94 720 bits, bien plus que les 10 752 bits du 8086, ce qui a rendu la conversion des images et la validation particulièrement difficiles
  • À partir d’images haute résolution du die, une combinaison de traitement d’image, réseaux neuronaux et automatisation assistée par l’humain a permis d’extraire un blob binaire en quelques jours et de le valider par recoupement
  • Au fil du désassemblage, l’organisation du tableau de μ-op, des champs de bits, des motifs de fin d’instruction, du décodeur d’instructions et de la PLA de tests de protection s’est progressivement révélée
  • Le 80386 dispose de microcode pour toutes les instructions, et de nombreuses routines servent moins à implémenter des algorithmes qu’à piloter le matériel de multiplication/division et le barrel shifter
  • Un défaut potentiel a été repéré dans le traitement de la bitmap de permissions d’E/S en mode protégé : lors d’un accès port sur 4 octets, seules les 3 premières adresses semblent être vérifiées, sans que cela soit encore confirmé

Extraction et désassemblage du microcode du 80386

  • Après le désassemblage du microcode du 8086, Ken Shirriff a fourni des images haute résolution de la ROM de microcode du 80386, mais avec 94 720 bits contre 10 752 pour le 8086, sa conversion et sa validation étaient nettement plus difficiles
  • Le 8086 disposait d’un brevet décrivant sa structure générale et quelques fragments de code, offrant des indices de recherche, mais le 80386 était proche d’une boîte noire complète, ce qui rendait difficile l’identification de structures dans un gros bloc binaire
  • Sur Discord, GloriousCow, Smartest Blob et d’autres ont poursuivi le travail d’extraction du microcode à partir d’images haute résolution du die du 80386, l’obstacle principal étant de transformer l’image en binaire puis en microcode compréhensible
  • En combinant traitement d’image, réseaux neuronaux et automatisation assistée par l’humain, ils ont extrait en quelques jours un blob binaire à partir des images, puis l’ont validé par recoupement

Structures révélées pendant le désassemblage

  • Même après l’extraction binaire, le désassemblage n’a pas été simple, et il a fallu faire correspondre divers motifs pour comprendre la réorganisation où un axe contient les μ-op et l’autre les bits de μ-op
  • La présence d’un bloc de μ-op inutilisé à une extrémité a fourni un indice sur l’ordre de lecture des μ-op
  • Pour découper les bits de μ-op en plusieurs champs, l’expérience acquise lors du travail sur le microcode du 8086 a permis d’identifier progressivement les champs des registres source et destination
  • Comme le 80386 peut exécuter une opération ALU en 2 cycles, il fallait un champ indiquant la seconde entrée de l’ALU afin de charger les deux opérandes au premier cycle puis d’envoyer le résultat vers la destination au second
  • Des motifs récurrents ont été supposés marquer la fin d’une instruction, ce qui a ensuite été confirmé
  • Ken a contribué à comprendre les connexions internes en retraçant plusieurs lignes et bits logiques du die du 80386, et chaque nouvelle structure découverte a servi d’indice pour interpréter d’autres fragments de microcode utilisant les mêmes éléments
  • Avec le microcode, le décodeur d’instructions composé de plusieurs petites PLA ainsi que la PLA de tests de protection ont aussi été décodés, ce qui a permis de relier les instructions 386 à des fragments de microcode

Un mode d’exécution différent de celui du 8086

  • Le 80386 est bien plus rapide par cycle que le 8086 pour la plupart des instructions, ce qui a nécessité davantage de transistors
  • Plusieurs algorithmes implémentés en microcode sur le 8086 sont, sur le 80386, pris en charge en pratique par des accélérateurs matériels
  • Une part importante du microcode du 80386 sert moins à l’algorithme lui-même qu’à configurer des accélérateurs comme le matériel de multiplication/division, le barrel shifter et l’unité de tests de protection
  • Une grande partie du travail de désassemblage a consisté à comprendre la façon dont ces interfaces d’accélérateurs étaient reliées au microcode

Points d’entrée du microcode et traitement des instructions

  • La ROM de décodage fournit 215 points d’entrée de microcode, contre 60 pour le 8086
  • Cette hausse ne s’explique pas seulement par l’ajout de nouvelles instructions : une même instruction peut aussi être traitée par des routines différentes selon que l’opérande est un registre ou de la mémoire, que le CPU est en mode réel ou protégé, ou qu’un préfixe REP est actif
  • La liste complète des points d’entrée se trouve dans le fichier fields.txt, avec les sous-routines et le code partagé
  • Beaucoup de routines de microcode de haut niveau effectuent très peu de travail avant de sauter vers une routine partagée avec d’autres points d’entrée, ce qui rend leur rôle difficile à déduire à partir de leur seule taille
  • Comme le décodeur d’instructions ne choisit pas la routine uniquement à partir de l’opcode, il est difficile de décrire la structure seulement par le nombre d’opcodes traités par chaque point d’entrée

Toutes les instructions passent par le microcode

  • Contrairement au 8086 ou aux CPU modernes, le 80386 exécute toujours des μ-op, et chaque instruction dispose d’un microcode correspondant
  • Il semble qu’aucune instruction ne soit traitée sans microcode

Code inutilisé et traces de gestion d’exceptions

  • Les routines de 0x849 à 0x856 sont marquées unused? dans le désassemblage du microcode et semblent ne correspondre à aucun point d’entrée relié
  • Leur fonctionnement exact n’est pas totalement certain, mais elles présentent de nombreux points communs avec la routine #PF(PAGE_FAULT) située de 0x8e9 à 0x8f5
  • Dans les deux cas, le dernier code d’erreur est défini dans l’unité de pagination puis l’exécution se poursuit vers l’interruption 0x0e
  • La différence est qu’ici CR2 semble recevoir une valeur inconnue issue de l’unité de pagination au lieu de l’adresse linéaire en faute
  • Le reste du microcode semble conçu pour implémenter le comportement documenté du CPU, tandis que les routines interagissant avec le matériel ICE (In-Circuit Emulator) de débogage bas niveau relèvent d’un comportement non documenté

Fonctionnalités cachées et défaut possible de la bitmap de permissions d’E/S

  • Cela n’a pas encore pu être confirmé sur une vraie machine 386, mais il pourrait exister un défaut dans le traitement de la bitmap de permissions d’E/S utilisée par certains OS en mode protégé pour autoriser partiellement l’accès aux ports d’E/S depuis des processus en mode utilisateur
  • Lors d’un accès port sur 4 octets, le microcode semble ne vérifier les bits de permission que pour les 3 premières adresses
  • Si un processus effectue un tel accès à la frontière d’une plage de ports d’E/S autorisée, le dernier accès octet pourrait réussir à tort et atteindre un registre matériel que l’OS ne voulait pas exposer à l’utilisateur
  • Ce bug serait extrêmement particulier et aurait pu passer inaperçu sans le désassemblage du microcode, mais il serait étonnant qu’une faille de sécurité sur un matériel utilisé aussi largement depuis plus de 40 ans n’ait jamais été découverte
  • Ce comportement a peut-être existé seulement sur certaines versions du CPU, ou bien l’interprétation de la routine est erronée et le fonctionnement réel est correct
  • Ce microcode ne semble pas provenir d’une toute première version du 80386, et les instructions XBTS et IBTS n’y laissent pratiquement aucune trace en dehors du décodeur

Ressources d’apprentissage et emplacement des téléchargements

1 commentaires

 
GN⁺ 2 시간 전
Commentaires sur Hacker News
  • Je me demande comment on peut reconstituer le microcode à partir d’images de puce en haute résolution
    Je voudrais aussi savoir si le processus consiste à identifier chaque transistor pour modéliser le circuit, et si le résultat prend une forme comparable à du Verilog

    • J’ai participé un peu au processus d’extraction : on commence par marquer les coordonnées x,y de tous les bits à partir des points d’intersection des lignes et des colonnes de la matrice de microcode
      Ensuite, on classe les 0 et les 1 ; les 1 se distinguent visuellement par la présence d’un transistor et par un espace dans le polysilicium
      Vu les caractéristiques du microcode d’Intel, on peut supposer qu’il y a beaucoup plus de 0 que de 1, donc quand il y avait un transistor, on l’a considéré comme un 1
      Il existe aussi des outils qui automatisent ça avec des seuils de couleur, mais certaines parties de la mosaïque étaient floues et il y avait de la poussière, ce qui créait beaucoup de faux bits à 1, donc ça collait mal
      À la place, on a entraîné un réseau neuronal convolutif à classer en 0/1 les zones de bits extraites, puis on a vérifié le résultat en superposant à la mosaïque d’origine des rectangles blancs/noirs avec une opacité de 50 %
      Ensuite, on a passé plusieurs jours à corriger les erreurs, de façon assez fastidieuse, et on a fini par obtenir une matrice 2D brute de bits ; l’étape suivante consiste à extraire de cette matrice les mots de microcode
    • Il existe une vidéo où l’on voit la puce du mécanisme de verrouillage de la Nintendo 64 être décapée couche par couche, et le sujet y est traité assez en profondeur sous plusieurs angles
      https://youtu.be/HwEdqAb2l50?si=VFLed64PZvpCHfy1
    • Il suffit de regarder l’image elle-même
      « La photo ci-dessus montre une partie de la ROM de microcode. Au microscope, on peut voir le contenu de la ROM de microcode, et lire les bits selon la présence ou l’absence d’un transistor à chaque emplacement »
      https://www.righto.com/2020/06/a-look-at-die-of-8086-process...
    • Le microcode se trouve dans une ROM, avec une structure régulière où les 1 et les 0 ont un aspect différent
  • Fil de discussion connexe en cours : z386: An Open-Source 80386 Built Around Original Microcode - https://news.ycombinator.com/item?id=48248014 - mai 2026, 22 commentaires

  • Quand j’ai consulté le blog de reenigne il y a quelques jours, je me suis dit : « tiens, aucun billet depuis 2020 » ; content de voir qu’il est de retour
    C’est aussi particulièrement amusant de voir que le blog remonte à il y a 33 ans

    • Le compteur de vues qui a augmenté lui a peut-être donné envie d’écrire
  • Un bon livre qui explique la microprogrammation depuis les bases : https://www.amazon.com/Computation-Structures-Optical-Electr...
    On peut aussi trouver facilement un PDF gratuit

  • L’effort nécessaire pour faire la rétro-ingénierie de ce microcode est impressionnant, et c’est un excellent article qui explore en profondeur l’architecture du 386

  • Voir une implémentation réelle de microcode rend moins mystérieuse la façon dont les anciens processeurs géraient les opérations complexes

  • Le 386 a connu de nombreux petits changements au cours de ses 22 années de production, donc il est important de savoir de quelle révision du 386 provient ce code

    • Un indice est la valeur chargée dans EDX au reset
      9B5 BIST1 -> TMPD 0x0303 PASS2
      9B6 SIGMA -> EDX
      9B7 BIST2 -> TMPE TMPD XOR
      9B8 SIGMA 0x3ddc0c2c XOR
      9B9 SIGMA -> EAX BOOTUP_JUMP JFPUOK
      0x303 signifie famille de produit 3, modèle 0, stepping ID 3
  • L’analyse en boîte noire nécessaire pour déchiffrer ça est incroyablement difficile, mais en cas de réussite, ça doit être extrêmement amusant et gratifiant

  • Je suis content d’avoir suivi à l’université des cours difficiles pour pouvoir comprendre des articles comme celui-ci, et c’est agréable aussi que HN, en 2015, ait stimulé ce genre de réflexion
    Même si je n’utilise plus beaucoup mes connaissances en programmation bas niveau aujourd’hui, chaque fois que je lis ce type d’article, j’ai l’impression que ça enrichit ma conscience, et c’est formidable
    Pour celles et ceux qui ont moins facilement accès à l’université, je recommande nand2tetris.org

    • Construire soi-même un microprocesseur à partir des portes logiques est une façon plus simple de comprendre la conception du microcode et le fonctionnement d’un processeur
      Étudier des conceptions anciennes et simples comme le RISC ou le Transputer peut aussi aider, et le 80386 se situe à l’extrémité opposée de ce spectre
      Il est devenu inutilement complexe à force de préserver de mauvais vieux choix de conception et la rétrocompatibilité
      Il n’est pas nécessaire de passer par l’université pour apprendre la conception de puces ; regarder quelques conférences d’Alan Kay ou parcourir les documents de conception informatique sur Bitsavers constitue aussi un bon point de départ
      J’ai créé Morphle Logic, qui permet de simuler une conception au niveau des portes d’une manière plus simple qu’avec un FPGA, puis de la convertir en transistors sur puce pour moins de 200 dollars aux tarifs de 2026
      À terme, cela pourrait déboucher sur une intégration en superordinateur à l’échelle du wafer, plus grande, plus rapide et moins chère
      https://github.com/fiberhood/MorphleLogic/blob/main/README_M...
      https://www.youtube.com/watch?v=vbqKClBwFwI
      https://www.youtube.com/watch?v=f1605Zmwek8
      http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/alto/...
    • J’ai fait nand2tetris plusieurs fois, mais comme le projet met l’accent sur la simplicité à tous les niveaux d’abstraction, il passe à côté de choses comme le microcode
      Cette simplicité en elle-même est une excellente leçon et m’a beaucoup inspiré, mais les cours d’électrotechnique que j’ai suivis à l’université dans les années 1990 ressemblaient à nand2tetris tout en expliquant aussi comment des CPU de type 8086 étaient construits, y compris le fonctionnement du microcode
      Le compteur de programme interne suivait une table de mots de contrôle, et chaque bit pilotait directement une partie contrôlable du CPU
      Chacun implémentait une instruction dans son simulateur ; moi, j’avais DEC, c’est-à-dire l’instruction de décrémentation
      D’une certaine manière, on pourrait considérer que les instructions de nand2tetris sont du microcode
      Les bits de l’instruction contrôlent directement le matériel, et le premier bit choisit entre deux types d’instructions, donc chaque instruction ne comporte qu’une seule étape de code
      Le microcode, lui, permet qu’une instruction ait un nombre arbitraire d’étapes de microcode
      Dans les vidéos de Ben Eater sur son CPU 8 bits sur breadboard, le mot de contrôle est déterminé en indexant une ROM avec les 4 bits d’opcode de l’instruction et un compteur d’étapes
      Cette ROM remplace une partie qu’on pourrait aussi réaliser avec des portes logiques suffisamment complexes, et comme il faut manipuler directement l’électronique et résoudre les problèmes qui surgissent, c’est une bonne étape suivante côté hardware
      Dommage toutefois qu’il n’y ait que 16 octets de RAM, ce qui rend plus difficile la construction de couches d’abstraction plus élevées comme dans nand2tetris
      À ce stade, on peut soit repartir sur une meilleure conception, soit passer sur PCB, soit basculer vers un projet 6502 pour penser ensemble timer, CPU, ROM, RAM, entrées/sorties, UART, etc., avant de passer à un microcontrôleur où tout cela est déjà intégré
      Si vous voulez lire un ouvrage expliquant comment construire un CPU à partir de portes logiques, Code de Charles Petzold progresse lentement et a été révisé récemment, tandis que The Pattern on the Stone de Danny Hillis va plus vite
      La 2e édition de Code utilise un compteur de cycles 4 bits et des portes logiques câblées en dur pour déterminer le comportement à chaque cycle, avec une matrice de diodes pour une partie de la logique ; je me demande si cela aussi devrait être considéré comme du microcode
    • Je me demande si nand2tetris traite du microcode ou s’en sert