1 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • A ROM de microcódigo do 80386 tem 94.720 bits, muito maior que os 10.752 bits do 8086, o que tornou a conversão e a verificação de imagens bem mais difíceis
  • A partir de imagens de alta resolução do die, foi extraído e validado em poucos dias um blob binário combinando processamento de imagem, redes neurais e automação assistida por humanos
  • No processo de desmontagem, foram sendo revelados gradualmente o arranjo de μ-ops, os campos de bits, os padrões de término de instrução, o decodificador de instruções e a estrutura da PLA de testes de proteção
  • O 80386 possui microcódigo para todas as instruções, e muitas rotinas servem mais para configurar o hardware de multiplicação/divisão e o barrel shifter do que para implementar algoritmos
  • Foi encontrado um possível defeito no tratamento do bitmap de permissão de E/S no modo protegido, no qual acessos de porta de 4 bytes aparentemente verificam apenas os 3 primeiros endereços, mas isso ainda não foi confirmado

Extração e desmontagem do microcódigo do 80386

  • Após o microcódigo do 8086 ser desmontado, Ken Shirriff forneceu imagens em alta resolução da ROM de microcódigo do 80386, mas a ROM do 80386, com 94.720 bits, é muito maior que a do 8086, com 10.752 bits, tornando conversão e verificação bem mais difíceis
  • O 8086 tinha uma patente com a estrutura geral e alguns trechos de código, o que dava pistas para a busca, mas o 80386 era praticamente uma caixa-preta completa, dificultando encontrar estrutura dentro de um grande bloco binário
  • No Discord, GloriousCow, Smartest Blob e outros continuaram o trabalho de extrair o microcódigo a partir de imagens em alta resolução do die do 80386, e o principal obstáculo era transformar imagem → binário → microcódigo compreensível
  • Combinando processamento de imagem, redes neurais e automação assistida por humanos, eles extraíram da imagem um blob binário e o validaram por verificação cruzada em poucos dias

Estruturas reveladas durante a desmontagem

  • Mesmo após a extração do binário, a desmontagem não foi fácil, e ao ajustar vários padrões foi possível descobrir uma reorganização em que um eixo continha os μ-ops e o outro os bits dos μ-ops
  • Havia um bloco de μ-ops não utilizado em uma das extremidades, o que serviu de pista para entender a ordem de leitura dos μ-ops
  • Ao dividir os bits dos μ-ops em vários campos, a experiência anterior com o microcódigo do 8086 ajudou a identificar campos de registradores de origem e destino
  • Como o 80386 pode executar operações da ALU em 2 ciclos, era necessário um campo que especificasse a segunda entrada da ALU para carregar os dois operandos no primeiro ciclo e enviar o resultado ao destino no segundo
  • Padrões que apareciam repetidamente foram considerados marcadores de fim de instrução e depois se confirmou que isso estava correto
  • Ken contribuiu rastreando vários fios e bits lógicos no die do 80386 para entender as conexões internas, e cada nova estrutura revelada ajudava a interpretar outros trechos de microcódigo que usavam os mesmos componentes
  • Junto com o microcódigo, também foram decifrados o decodificador de instruções, composto por várias pequenas PLAs, e a PLA de testes de proteção, o que permitiu ligar instruções do 386 aos trechos correspondentes de microcódigo

Como a execução do 80386 difere da do 8086

  • O 80386 é muito mais rápido por ciclo do que o 8086 na maioria das instruções, e para isso usa mais transistores
  • Vários algoritmos que eram implementados em microcódigo no 8086 passaram, no 80386, a ser tratados por verdadeiros aceleradores de hardware
  • Grande parte do microcódigo do 80386 serve mais para configurar aceleradores como o hardware de multiplicação/divisão, o barrel shifter e a unidade de testes de proteção do que para executar o algoritmo em si
  • Uma parte importante do trabalho de desmontagem foi entender como essas interfaces dos aceleradores se conectam ao microcódigo

Pontos de entrada do microcódigo e processamento de instruções

  • Há 215 pontos de entrada de microcódigo acessados a partir da ROM de decodificação, um aumento grande em relação aos 60 do 8086
  • Esse aumento não se deve apenas a novas instruções, mas também ao fato de que a mesma instrução pode ser tratada por rotinas diferentes dependendo de o operando estar em registrador ou memória, de a CPU estar em modo real ou protegido e de um prefixo REP estar em uso
  • A lista completa de entradas está no arquivo fields.txt, junto com sub-rotinas e código compartilhado
  • Muitas rotinas de microcódigo de nível superior fazem pouco trabalho antes de saltar para rotinas compartilhadas com outros pontos de entrada, então o tamanho da rotina superior por si só não basta para entender seu significado
  • Como o decodificador de instruções não usa apenas o opcode para escolher a rotina, também é difícil explicar a estrutura apenas pelo número de opcodes tratados por cada ponto de entrada

Todas as instruções são tratadas por microcódigo

  • Diferentemente do 8086 ou de CPUs modernas, o 80386 sempre executa μ-ops, e existe microcódigo correspondente para todas as instruções
  • Foi confirmado que não há instruções tratadas sem microcódigo

Código não utilizado e vestígios de tratamento de exceções

  • As rotinas de 0x849 a 0x856 aparecem marcadas como unused? na desmontagem do microcódigo e parecem não ter pontos de entrada conectados
  • O funcionamento exato dessas rotinas não é totalmente certo, mas elas têm muitas semelhanças com as rotinas #PF(PAGE_FAULT) de 0x8e9 a 0x8f5
  • Em ambos os casos, o último código de erro da unidade de paginação é configurado e depois o fluxo segue para a interrupção 0x0e
  • A diferença é que essas rotinas parecem gravar em CR2 um valor desconhecido vindo da unidade de paginação, em vez do fault linear address
  • O restante do microcódigo parece ter sido projetado para implementar o comportamento documentado da CPU, enquanto rotinas que interagem com hardware ICE (In-Circuit Emulator) de depuração de baixo nível correspondem a comportamentos não documentados

Recursos ocultos e possível falha no bitmap de permissão de E/S

  • Ainda não foi possível confirmar em uma máquina 386 real, mas pode haver uma falha no tratamento do bitmap de permissão de E/S, usado por alguns sistemas operacionais em modo protegido para permitir acesso limitado de processos em modo usuário a portas de E/S
  • Quando ocorre um acesso de porta de 4 bytes, o microcódigo parece verificar apenas os bits de permissão dos 3 primeiros endereços
  • Se um processo fizer esse acesso na fronteira de uma área de portas de E/S para a qual tem permissão, o acesso ao último byte pode acabar sendo aceito indevidamente, permitindo tocar em um registrador de hardware ao qual o SO não pretendia dar acesso
  • Esse bug é muito específico e poderia ter passado despercebido sem a desmontagem do microcódigo, mas ainda assim é incomum que uma falha de segurança em hardware tão amplamente usado por mais de 40 anos não tenha sido descoberta
  • Esse comportamento pode ter existido apenas em algumas versões da CPU, ou a interpretação da rotina pode estar errada e o funcionamento real ser o correto
  • Este microcódigo não parece ser de uma versão inicial do 80386, e as instruções XBTS e IBTS não deixam vestígios além do decodificador

Material de estudo e onde baixar

1 comentários

 
GN⁺ 2 시간 전
Comentários no Hacker News
  • Fiquei curioso sobre como é possível restaurar o microcódigo a partir de imagens de die em alta resolução
    Queria entender se o processo consiste em identificar cada transistor para modelar o circuito, e se o resultado fica em algo como Verilog

    • Participei um pouco do processo de extração; primeiro, marcamos as coordenadas x,y de todos os bits com base nos pontos onde linhas e colunas da matriz de microcódigo se cruzam
      Depois classificamos 0 e 1; o 1 era distinguido visualmente pela presença de transistor e pela lacuna no polissilício
      Pelas características do microcódigo da Intel, dava para assumir que havia muito mais 0 do que 1, então, se havia transistor, considerávamos 1
      Existem ferramentas que fazem isso automaticamente por limiar de cor, mas algumas partes do mosaico estavam borradas e havia poeira, o que gerava muitos bits 1 falsos, então não funcionou bem
      Em vez disso, treinamos uma rede neural convolucional para classificar as regiões de bits extraídas como 0/1 e conferimos o resultado cobrindo o mosaico original com retângulos brancos/pretos com 50% de transparência
      Depois passamos vários dias revisando erros de forma tediosa e, por fim, obtivemos a matriz bruta bidimensional de bits; a próxima etapa é extrair dessa matriz as palavras de microcódigo
    • Há um vídeo mostrando um chip do mecanismo de bloqueio do Nintendo 64 sendo removido camada por camada, e ele aborda esse tipo de trabalho com bastante profundidade de várias formas
      https://youtu.be/HwEdqAb2l50?si=VFLed64PZvpCHfy1
    • Basta olhar para a própria imagem
      “A foto acima mostra uma parte da ROM de microcódigo. Ao microscópio, dá para ver o conteúdo da ROM de microcódigo, e é possível ler os bits dependendo de haver ou não transistor em cada posição”
      https://www.righto.com/2020/06/a-look-at-die-of-8086-process...
    • O microcódigo fica em ROM, e é uma estrutura regular em que 1 e 0 têm aparências diferentes
  • Thread relacionada em andamento: z386: An Open-Source 80386 Built Around Original Microcode - https://news.ycombinator.com/item?id=48248014 - maio de 2026, 22 comentários

  • Quando vi o blog do reenigne alguns dias atrás, pensei “hmm, não tem post desde 2020”, então foi bom vê-lo voltar
    Também é especialmente interessante que o blog tenha histórico de 33 anos

    • Talvez o aumento no contador de visualizações tenha sido o incentivo para escrever
  • Um bom livro que explica microprogramação desde a base: https://www.amazon.com/Computation-Structures-Optical-Electr...
    Também é fácil encontrar um PDF gratuito

  • O esforço necessário para fazer a engenharia reversa desse microcódigo é impressionante, e é um excelente texto que mergulha fundo na arquitetura do 386

  • Ver uma implementação real de microcódigo torna menos misterioso como processadores antigos lidavam com operações complexas

  • O 386 teve muitas pequenas mudanças ao longo de seus 22 anos de produção, então é importante saber de qual revisão do 386 esse código veio

    • Uma pista é o valor carregado em EDX no 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 significa família 3, modelo 0, stepping ID 3
  • A análise de caixa-preta necessária para decifrar isso é absurdamente difícil, mas, se der certo, parece muito divertida e recompensadora

  • É satisfatório ter cursado disciplinas difíceis na faculdade para conseguir entender textos como esse, e também foi legal que o HN naquela época, em 2015, estimulasse esse tipo de pensamento
    Hoje eu já não uso tanto conhecimento de programação de baixo nível, mas toda vez que leio algo assim sinto que minha consciência fica mais rica, o que é muito bacana
    Para quem tem pouco acesso à universidade, recomendo nand2tetris.org

    • Construir um microprocessador começando pelos próprios gates é uma forma mais fácil de entender projeto de microcódigo e o funcionamento do processador
      Estudar projetos antigos e simples, como RISC ou Transputer, também ajuda, e o 80386 está no extremo oposto desse espectro
      Isso porque ele ficou desnecessariamente complexo ao tentar manter compatibilidade retroativa com projetos antigos ruins
      Não é obrigatório passar por uma universidade para aprender projeto de chips; assistir a algumas palestras do Alan Kay ou folhear materiais de projeto de computadores no Bitsavers também é um bom começo
      Criei o Morphle Logic para simular projeto em nível de gate de um jeito mais fácil que FPGA e converter isso em transistores em chip por menos de 200 dólares em valores de 2026
      No fim, isso pode evoluir para integração em supercomputadores em escala de wafer cada vez maiores, mais rápidos e mais baratos
      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á fiz nand2tetris algumas vezes, mas ele pula coisas como microcódigo porque enfatiza simplicidade em todos os níveis de abstração
      Essa simplicidade em si é uma grande lição e me inspirou bastante, mas as aulas de engenharia elétrica que fiz na faculdade nos anos 1990 eram parecidas com nand2tetris, só que também mostravam como CPUs do tipo 8086 eram construídas, incluindo a explicação de como o microcódigo funcionava
      Havia um contador de programa interno que percorria uma tabela de palavras de controle, e cada bit coordenava diretamente uma parte controlável da CPU
      Cada aluno implementava uma instrução em seu simulador; eu fiquei com DEC, isto é, a instrução de decremento
      Em certo sentido, as instruções do nand2tetris também podem ser vistas como microcódigo
      Os bits da instrução controlam o hardware diretamente, e o primeiro bit escolhe entre dois tipos de instrução, então cada instrução tem apenas 1 etapa de código
      Já no microcódigo, uma instrução pode ter um número arbitrário de etapas de microcódigo
      Nos vídeos da CPU breadboard de 8 bits do Ben Eater, a palavra de controle é determinada indexando a ROM com o opcode de 4 bits da instrução e o contador de etapas
      Essa ROM substitui uma parte que também poderia ser feita com portas lógicas suficientemente complexas e, como exige mexer diretamente com eletrônica e resolver problemas, é um bom próximo passo no lado do hardware
      Só é uma pena que a RAM tenha apenas 16 bytes, o que dificulta construir camadas de abstração mais altas como no nand2tetris
      Nesse ponto, dá para refazer com um projeto melhor, passar para PCB ou ir para um projeto com 6502 para pensar CPU, ROM, RAM, E/S, UART e temporizadores como um sistema integrado, antes de então migrar para microcontroladores onde tudo isso já vem junto
      Se quiser ler sobre como construir uma CPU com portas lógicas, Code, de Charles Petzold, explica devagar e foi revisado recentemente, enquanto The Pattern on the Stone, de Danny Hillis, avança mais rápido
      A 2ª edição de Code usa um contador de ciclo de 4 bits e lógica hardwired para definir a ação de cada ciclo, além de usar arranjos de diodos em parte da lógica; fico curioso se isso também deveria ser considerado microcódigo
    • Fiquei curioso se nand2tetris aborda ou usa microcódigo