Hacking DDR3 SPD

Atualizei meu laptop antigo com dois módulos de memória DDR3-1333 de 4 GB, mas o laptop é compatível com no máximo DDR3-1066. O que um homem de verdade fará? Obviamente, ele atualizará a EEPROM para religar a DDR3 para um modelo mais lento!


Local de trabalho. À direita está o Thinkpad para piscar, e à esquerda está o problemático MacBook Pro

Tenha muito cuidado. Obviamente, você pode corromper ou bloquear permanentemente a gravação no seu DIMM. Possíveis problemas mais sutis, incluindo uma falha no circuito lógico da bateria, ou a placa-mãe se transformará em um tijolo .

Como tudo começou


Eu tenho um MacBook Pro de 13 polegadas em meados de 2010. Seu sistema de arquivos foi danificado durante uma reinicialização regular e o utilitário de disco (da partição de recuperação) não pôde fazer nada sobre isso. Bem, eu estou esperando por isso há muito tempo: é hora de colocar um SSD e adicionar um pouco de RAM.

Comprei um SSD e tive a sorte de encontrar alguns laptops quebrados com módulos de RAM adequados na montanha de lixo eletrônico. Inserimos o SSD e dois módulos de 4 GB, lançamos o Internet Recovery - e em uma hora devemos ter um sistema em funcionamento. Mas não. Baixe apenas congela. Por causa do que? A maior suspeita é causada por esses módulos de RAM, afinal, eles são de lixo. Portanto, fazemos o que qualquer um faria: crie uma unidade flash USB com o memtest86 e execute-a durante a noite. Ótimo, a memória está boa. Depois de muitas horas testando diferentes métodos de instalação para diferentes versões do macOS, finalmente surge a descoberta de que tudo funciona bem simplesmente reinserindo a memória antiga. 1

Verdadeira razão


Percebendo o problema, descobri rapidamente que o MacBook 2009-2010 não funcionava com memória mais rapidamente que o PC3-8500 e que o problema poderia ser contornado modificando os metadados da RAM usando um programa do Windows chamado Thaiphoon Burner .

A verdadeira causa da falha é o processador gráfico GeForce 320M, que usa memória compartilhada, ou seja, RAM comum. Ele pode funcionar no máximo com PC3-8500 (também conhecido como DDR3-1066, ou seja, com uma frequência de clock de 533 MHz DRAM), mas o controlador de memória do sistema não o conhece e aumenta a velocidade máxima disponível para 667 MHz (ou seja, PC3-10600 ou DDR3 -1333). Os componentes restantes não têm problemas com isso, assim como a GPU no modo VESA (eu acho).

Não ouvi nenhum outro equipamento que falhe na operação da RAM capaz de velocidades mais altas do que o equipamento pode usar. Obviamente, ao comprar módulos de memória no mercado, os vendedores teriam alertado sobre essa nuance. Isso ainda é muito melhor do que uma RAM soldada, como nos laptops da Apple desde 2012.

Configuração de firmware


Depois de descobrir o motivo, instalei um módulo PC3-8500 original em 2 GB e um novo módulo de 4 GB, e funcionou. Mas o reinício do DDR3 parecia um bom projeto, então decidi experimentá-lo.

Obviamente, não instalarei o Windows apenas para o firmware da EEPROM e não comprarei software sofisticado, se tudo puder ser feito manualmente. Eu pensei que a tarefa obviamente deveria ser feita no Linux, talvez com algumas ferramentas adicionais. Eu também não queria instalar o Linux em um macbook apenas para isso. Portanto, meu antigo e confiável Thinkpad X220 com NixOS se tornou uma plataforma ideal para o trabalho. Demorou um pouco para atualizá-lo, porque não carregava o carro por mais ou menos um ano.

Então foi a vez de escolher qual módulo tentar primeiro. O Thinkpad já tinha dois de 4 GB cada, e eu encontrei quatro módulos de 4 GB, então tinha muito por onde escolher. Decidi começar com a produção Micron mais estranha. Todo o resto era Samsung. Um deles tinha um adesivo da Lenovo.

Leia SPD


Os módulos de memória vêm com um chip EEPROM que contém metadados sobre o módulo Serial Presence Detect (SPD). O formato em si é simples e o acesso à EEPROM pode ser organizado através do barramento SMBus , que é essencialmente o mesmo que I²C . 2

Felizmente, existem drivers de kernel e software pronto para interagir com o SMBus e até ler EEPROM DDR3.

Primeiramente, para visualizar os dispositivos no barramento, são necessárias as i2c-tools e alguns módulos do kernel.

$ nix-shell -p i2c-tools
$ modprobe i2c-dev
$ modprobe i2c-i801
$ i2cdetect -l
i2c-0 unknown i915 gmbus ssc N/A
i2c-1 unknown i915 gmbus vga N/A
i2c-2 unknown i915 gmbus panel N/A
i2c-3 unknown i915 gmbus dpc N/A
i2c-4 unknown i915 gmbus dpb N/A
i2c-5 unknown i915 gmbus dpd N/A
i2c-6 unknown DPDDC-B N/A
i2c-7 unknown DPDDC-C N/A
i2c-8 unknown DPDDC-D N/A
i2c-9 unknown SMBus I801 adapter at efa0 N/A


O adaptador SMBus é interessante aqui, no meu caso i2c-9 .

O pacote i2c-tools ainda vem com uma decode-dimms para ler as informações da RAM em um formato legível. Isso requer o módulo eeprom kernel.

$ modprobe eeprom
$ decode-dimms
$ modprobe -r eeprom


Aqui está a saída para um módulo de memória:

  Decodificador de Detecção de Presença Serial de Memória
 Por Philip Edelbrock, Christian Zuckschwerdt, Burkart Lingner,
 Jean Delvare, Trent Piepho e outros


 Decodificando EEPROM: / sys / bus / i2c / drivers / eeprom / 9-0050
 Adivinhar dimm está no banco 1

 --- === Informações da EEPROM SPD === ---
 CRC EEPROM dos bytes 0-116 OK (0xAEA4)
 Nº de bytes gravados na SDRAM EEPROM 176
 Número total de bytes na EEPROM 256
 Tipo de memória fundamental DDR3 SDRAM
 Tipo de módulo SO-DIMM

 --- === Características da memória === ---
 Velocidade máxima do módulo 1333 MHz (PC3-10600)
 Tamanho 4096 MB
 Bancos x Linhas x Colunas x Bits 8 x 15 x 10 x 64
 Fileiras 2
 Largura do dispositivo SDRAM 8 bits
 Extensão de Largura do Barramento 0 bits
 tCL-tRCD-tRP-tRAS 9-9-9-24
 Latências CAS suportadas (tCL) 10T, 9T, 8T, 7T, 6T, 5T

 --- === Horários em velocidades padrão === ---
 tCL-tRCD-tRP-tRAS como DDR3-1333 9-9-9-24
 tCL-tRCD-tRP-tRAS como DDR3-1066 7-7-7-20
 tCL-tRCD-tRP-tRAS como DDR3-800 6-6-6-15

 --- === Parâmetros de tempo === ---
 Tempo mínimo de ciclo (tCK) 1.500 ns
 Tempo mínimo de latência da CAS (tAA) 13,125 ns
 Tempo mínimo de recuperação de gravação (tWR) 15.000 ns
 Atraso mínimo de RAS em CAS # (tRCD) 13,125 ns
 Atraso mínimo de linha ativa para linha ativa (tRRD) 6.000 ns
 Atraso mínimo de pré-carga de linha (tRP) 13,125 ns
 Atraso mínimo ativo para pré-carga (tRAS) 36.000 ns
 Atraso mínimo ativo para atualização automática (tRC) 49,125 ns
 Atraso mínimo de recuperação (tRFC) 160.000 ns
 Atraso mínimo no CMD de gravação para leitura (tWTR) 7.500 ns
 Atraso mínimo de leitura para pré-cobrança de CMD (tRTP) 7.500 ns
 Atraso mínimo de quatro janelas de ativação (tFAW) 30.000 ns

 --- === Recursos opcionais === ---
 Tensões operacionais 1.5V
 RZQ / 6 suportado?  Não
 RZQ / 7 suportado?  Sim
 Modo DLL-Off suportado?  Sim
 Faixa de temperatura operacional 0-95 graus C
 Taxa de atualização no intervalo de temperatura estendido 2X
 Atualização automática automática?  Sim
 Leitura do sensor térmico no molde?  Não
 Atualização parcial da matriz parcial?  Não
 Sensor térmico do módulo Sim
 Tipo de dispositivo SDRAM monolítico padrão

 --- === Características físicas === ---
 Altura do módulo 30 mm
 Espessura do módulo 2 mm à frente, 2 mm atrás
 Largura do módulo 67,6 mm
 Cartão de Referência do Módulo F revisão 0
 Padrão de Mapeamento Grau 1

 --- === Dados do fabricante === ---
 Fabricante de módulos Micron Technology
 Fabricante de DRAM Micron Technology
 Código de local de fabricação 0x0F
 Data de fabricação 2011-W23
 Número de série do conjunto 0xFB5C7F1A
 Número da peça 16JSF51264HZ-1G4D1
 Código de revisão 0x4431 

Praticamente dados. Parte das informações mostradas é calculada a partir dos dados. Por exemplo, tempos em velocidades padrão (ou seja, contagens de ciclo) são calculados com base em parâmetros de tempo em resolução de nanossegundos. Mesmo eles são armazenados como múltiplos da unidade base de tempo instalada em outro local na EEPROM, mas isso não se aplica ao tópico do artigo. Este módulo de RAM fornece 7-7-7-20 para DDR3-1066, em conformidade com o padrão DDR3-1066F JEDEC. Não me pergunte o que é JEDEC, mas é mais rápido que o mais barato DDR3-1066G.

Passei muito tempo confirmando minha conclusão: ao tentar refazer a memória, o único número importante é o tempo mínimo de ciclo (tCK). Aqui estão 1,5 ns, ou seja, 667 MHz.

Vamos dar uma olhada nos dados de origem.

  $ i2cdump 9 0x50
 Nenhum tamanho especificado (usando acesso a dados de bytes)
 ATENÇÃO!  Este programa pode confundir o seu barramento I2C, causar perda de dados e muito mais!
 Vou pesquisar o arquivo / dev / i2c-9, endereço 0x50, modo byte
 Continuar?  [S / n]
      0 1 2 3 4 5 6 7 8 9 abcdef 0123456789abcdef
 00: 92 10 0b 03 03 19 00 09 03 52 01 08 0c 00 7e 00 ??????. ?? R ???. ~.
 10: 69 78 69 30 69 11 20 89 00 05 3c 3c 00 f0 82 05 ixi0i?  ?.? <<. ???
 20: 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00? ...............
 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 11 05 00 ............ ???.
 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 70: 00 00 00 00 00 80 2c 0f 11 23 fb 5c 7f 1a a4 ae .....?, ?? #? \ ????
 80: 31 36 4a 53 46 35 31 32 36 34 48 5a 2d 31 47 34 16JSF51264HZ-1G4
 90: 44 31 44 31 80 2c 00 00 00 00 00 00 00 00 00 00 00 D1D1 ?, ..........
 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
 c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
 d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
 e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
 f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 

As especificações dizem que o tempo mínimo é indicado em 0x0c. Vamos ver, está na primeira linha ( 00: , na coluna c . A propósito, seu valor também é 0x0c ou 12. Esse é um múltiplo da base de tempo médio (MTB), que é o quociente de dividir o valor em 0x0a pelo valor em 0x0b (em nanossegundos). Aqui 1⁄8 ns. Então 12 MTB corresponde a 1,5 ns.

Planejamento de mudanças


Para descer para DDR3-1066, precisamos de 533 MHz, que é 1.875 ns ou 15 MTB, ou 0x0f. Ou seja, queremos escrever 0x0f em 0x0c.

Mas espere, obviamente, há uma correção de bug. O CRC dos primeiros 116 bytes é armazenado em 0x7e-7f. Olhei lá e vi a4 ae , depois fui procurar uma calculadora para cálculo. Levei um tempo incrivelmente longo para encontrar uma calculadora CRC viável. Eu tentei várias ferramentas de linha de comando, mas ainda assim resolvi a calculadora on-line http://crccalc.com/ . Então eu descobri que a variante CRC-16 / XMODEM é usada aqui e a soma de verificação é realmente 0xAEA4. Ordem de bytes e tudo isso. Deve-se notar na emissão de decode-dimms .

Portanto, você precisa escrever um novo tempo mínimo de ciclo (0x0f) em 0x0c e uma nova soma de verificação em 0x7e como uma palavra.

Registro SPD


Agora eu sabia o que escrever e finalmente me atrevi a tentar. Com mãos trêmulas, digitei y , apertei Enter para confirmação final e ...

  $ i2cset 9 0x50 0x0c 0x0f
 ATENÇÃO!  Este programa pode confundir o seu barramento I2C, causar perda de dados e muito mais!
 PERIGOSO!  Gravando em uma EEPROM serial em um DIMM de memória
 pode tornar sua memória INÚTIL e tornar seu sistema INESQUECÍVEL!
 Escreverei no arquivo de dispositivo / dev / i2c-9, endereço de chip 0x50, endereço de dados
 0x0c, dados 0x0f, byte de modo.
 Continuar?  [s / N] y
 Erro: falha na gravação 

O erro Espera o que?

Como um pedante, comecei a estudar as fontes do i2cset, bem como os módulos correspondentes do kernel. Em algum momento, percebi que isso poderia ser causado pela proteção contra gravação.

Peguei um módulo de memória, olhei para ele e reconheci o chip EEPROM. Diz 97B , 321 e algumas outras coisas. Pesquisando, descobri que este é um chip SE97B . Olhei para a tabela de dados e li atentamente a seção de proteção contra gravação várias vezes. Com a ajuda de programas, fiz várias tentativas para remover a proteção temporária contra gravação, mas falhei. A proteção contra gravação provavelmente era constante, então decidi procurar um módulo que não possui proteção contra gravação.

Um fato engraçado, a propósito, é que a proteção contra gravação em tempo real é ativada gravando algo em um endereço específico. Não acho que o i2cdetect faça isso normalmente, mas a execução do i2cget 9 0x30 <any-address> provavelmente definirá a proteção contra gravação em tempo real, o que é realmente constante. Eu não tentei fazer isso.

Peguei o módulo a seguir e não havia nenhuma mensagem de erro lá. A EEPROM simplesmente não mudou.

Finalmente, sucesso!


Com o terceiro módulo, a operação finalmente acabou. Eu calculei o CRC e escrevi junto com o tempo do ciclo. Após carregar o módulo do kernel da eeprom e iniciar decode-dimms módulo parecia um PC3-8500 de 4 GB comum. Quando o instalei no meu MacBook Pro, finalmente iniciei um sistema com 8 GB de memória.


O DDR3 SODIMM após o reinício está pronto para funcionar no MacBook Pro

Antes: DDR3-1333 original


  0 1 2 3 4 5 6 7 8 9 abcdef 0123456789abcdef
 00: 92 10 0b 03 03 19 00 09 03 52 01 08 0c 00 3e 00 ??????. ?? R ???.>.
 10: 69 78 69 30 69 11 20 89 00 05 3c 3c 00 f0 83 01 ixi0i?  ?.? <<. ???
 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 11 45 00 ............ ??
 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 70: 00 00 00 00 00 80 ce 02 11 30 b1 5b 13 a1 0e 59 ..... 0? [??? Y
 80: 4d 34 37 31 42 35 32 37 33 43 48 30 2d 43 48 39 M471B5273CH0-CH9
 90: 20 20 00 00 80 ce 00 00 00 53 31 42 4e 30 30 30 .. ?? ... S1BN000
 a0: 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 03?.? ............?
 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 59 00 ............. 2A.
 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 

Depois: parece DDR3-1066


  0 1 2 3 4 5 6 7 8 9 abcdef 0123456789abcdef
 00: 92 10 0b 03 03 19 00 09 03 52 01 08 0f 00 3e 00 ??????. ?? R ???.>.
 10: 69 78 69 30 69 11 20 89 00 05 3c 3c 00 f0 83 01 ixi0i?  ?.? <<. ???
 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 11 45 00 ............ ??
 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 70: 00 00 00 00 00 80 ce 02 11 30 b1 5b 13 a1 06 54 ..... 0? [??? T
 80: 4d 34 37 31 42 35 32 37 33 43 48 30 2d 43 48 39 M471B5273CH0-CH9
 90: 20 20 00 00 80 ce 00 00 00 53 31 42 4e 30 30 30 .. ?? ... S1BN000
 a0: 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 03?.? ............?
 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 59 00 ............. 2A.
 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 

Se você não perceber imediatamente a diferença, não se aprofundará nesses aterros por tanto tempo quanto eu.

Seus pensamentos


Vale a pena fazer? Financeiramente, claro que não!

Mas foi divertido e eu aprendi muito. Não tenho idéia de onde exatamente esse conhecimento pode ser aplicado, mas sinto que em algum momento eles serão necessários. E apenas a sensação de que você pode resolver o problema corretamente é realmente agradável e dá confiança.



1. Minha suposição de que a RAM funcionará neste equipamento se passar no memtest86 estava obviamente errada. No entanto, mesmo olhando para trás, a suposição não parece boba. Por experiência, uma estranha combinação de hardware não é incomum, devido à qual o teste padrão cai.

2. Recentemente, aprendi sobre o uso do I²C em outro projeto. Acho que posso ler e escrever EEPROM no microcontrolador Cortex-M usando meu próprio programa, mas, na prática, soldar o conector será muito difícil, e escrever código é muito trabalho para me interessar. No entanto, estou realmente feliz por ser teoricamente capaz de uma coisa dessas!

Source: https://habr.com/ru/post/pt431128/


All Articles