Главная » Хабрахабр » [Перевод] Хакаем DDR3 SPD

[Перевод] Хакаем DDR3 SPD

Я проапгрейдил старый ноутбук двумя модулями памяти 4GB DDR3-1333, но оказалось, что ноутбук совместим максимум с DDR3-1066. Что сделает настоящий мужчина? Конечно, перепрошьёт EEPROM модуля для ребиннинга DDR3 на более медленную модель!

Справа Thinkpad для проведения перепрошивки, а слева проблемный MacBook Pro
Рабочее место.

Очевидно, что вы можете повредить или навсегда заблокировать запись на свой DIMM. Будьте очень осторожны. Возможные более тонкие неполадки, в том числе сбой логической схемы батареи, или материнская плата превратится в кирпич.

У меня 13-дюймовый MacBook Pro середины 2010 года. Его файловая система была повреждена при обычной перезагрузке, и дисковая утилита (из раздела восстановления) ничего не могла с этим поделать. Ну, я давно этого ждал: пришло время поставить SSD и добавить немного оперативной памяти.

Вставляем SSD и два модуля по 4 ГБ, запускаем Internet Recovery — и через час у нас должна быть рабочая система. Я купил SSD и мне повезло найти в горе электронного мусора пару сломанных ноутбуков с подходящими модулями оперативной памяти. Загрузка просто зависает. Но нет. Наибольшее подозрение вызывают эти модули RAM, в конце концов, они же из мусора. Из-за чего? Отлично, память в порядке. Поэтому делаем то, что сделал бы любой: создаём USB-флэшку с memtest86 и запускаем её на ночь. 1 После многих часов с пробами разных методов установки для разных версий macOS наконец приходит открытие, что всё работает отлично, если просто вставить обратно старую память.

Понимая проблему, я быстро узнал, что MacBook Pro 2009−2010 годов на самом деле не работают с памятью быстрее, чем PC3-8500, и что проблему можно обойти, изменив метаданные RAM с помощью программы Windows под названием Thaiphoon Burner.

Он может работать максимум с PC3-8500 (aka DDR3-1066, то есть с тактовой частотой DRAM 533 МГц), но контроллер системной памяти не знает об этом и повышает максимальную доступную скорость до 667 МГц (т.е. Истинной причиной сбоя является интегрированный графический процессор GeForce 320M, который использует общую память, то есть обычную RAM. У остальных компонентов нет проблем с этим, как и у GPU в режиме VESA (я думаю). PC3-10600 aka DDR3-1333).

Конечно, при покупке модулей памяти на рынке продавцы предупредили бы об этом нюансе. Я не слышал ни о каком другом оборудовании, которое отказывает в работе оперативной памяти, способной к более высоким скоростям, чем оборудование может использовать. Это всё равно намного лучше, чем припаянная оперативка, как в ноутбуках Apple с 2012 года.

Разобравшись с причиной, я установил один оригинальный модуль PC3-8500 на 2 ГБ и один новый модуль 4 ГБ, и всё заработало. Но ребиннинг DDR3 казался хорошим проектом, поэтому я решил попробовать.

Я думал, что задача явно должна выполняться в Linux, возможно, с некоторыми дополнительными инструментами. Конечно, я не собираюсь устанавливать Windows только для прошивки EEPROM и не собираюсь покупать причудливое программное обеспечение, если всё можно сделать вручную. Поэтому мой старый надёжный Thinkpad X220 с NixOS стал идеальной площадкой для работ. Я также не хотел устанавливать Linux на макбук только для этого. Потребовалось немного времени для его обновления, потому что я не загружал машину год или около того.

У Thinkpad уже было два по 4 ГБ, и я нашел четыре модуля 4 ГБ, поэтому мне было из чего выбрать. Затем наступил черёд выбрать, какой модуль попробовать первым. Все остальные были Samsung. Я решил начать с самого странного, производства Micron. У одного была наклейка Lenovo.

Модули памяти поставляются с микросхемой EEPROM, которая содержит метаданные о модуле Serial Presence Detect (SPD). Сам формат простой, а доступ к EEPROM можно организовать через шину SMBus, которая по сути не отличается от I²C.2

К счастью, для взаимодействия с SMBus и даже чтения EEPROM DDR3 есть драйверы ядра и готовое программное обеспечение.

Во-первых, для просмотра устройств на шине нужны i2c-tools и некоторые модули ядра.

$ 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

Здесь представляет интерес адаптер SMBus, в моём случае i2c-9.

Для этого требуется модуль ядра eeprom. Пакет i2c-tools поставляется даже с инструментом decode-dimms для чтения информации о RAM в удобочитаемом формате.

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

Вот часть выдачи для одного модуля памяти:

Memory Serial Presence Detect Decoder
By Philip Edelbrock, Christian Zuckschwerdt, Burkart Lingner,
Jean Delvare, Trent Piepho and others Decoding EEPROM: /sys/bus/i2c/drivers/eeprom/9-0050
Guessing DIMM is in bank 1 ---=== SPD EEPROM Information ===---
EEPROM CRC of bytes 0-116 OK (0xAEA4)
# of bytes written to SDRAM EEPROM 176
Total number of bytes in EEPROM 256
Fundamental Memory type DDR3 SDRAM
Module Type SO-DIMM ---=== Memory Characteristics ===---
Maximum module speed 1333 MHz (PC3-10600)
Size 4096 MB
Banks x Rows x Columns x Bits 8 x 15 x 10 x 64
Ranks 2
SDRAM Device Width 8 bits
Bus Width Extension 0 bits
tCL-tRCD-tRP-tRAS 9-9-9-24
Supported CAS Latencies (tCL) 10T, 9T, 8T, 7T, 6T, 5T ---=== Timings at Standard Speeds ===---
tCL-tRCD-tRP-tRAS as DDR3-1333 9-9-9-24
tCL-tRCD-tRP-tRAS as DDR3-1066 7-7-7-20
tCL-tRCD-tRP-tRAS as DDR3-800 6-6-6-15 ---=== Timing Parameters ===---
Minimum Cycle Time (tCK) 1.500 ns
Minimum CAS Latency Time (tAA) 13.125 ns
Minimum Write Recovery time (tWR) 15.000 ns
Minimum RAS# to CAS# Delay (tRCD) 13.125 ns
Minimum Row Active to Row Active Delay (tRRD) 6.000 ns
Minimum Row Precharge Delay (tRP) 13.125 ns
Minimum Active to Precharge Delay (tRAS) 36.000 ns
Minimum Active to Auto-Refresh Delay (tRC) 49.125 ns
Minimum Recovery Delay (tRFC) 160.000 ns
Minimum Write to Read CMD Delay (tWTR) 7.500 ns
Minimum Read to Pre-charge CMD Delay (tRTP) 7.500 ns
Minimum Four Activate Window Delay (tFAW) 30.000 ns ---=== Optional Features ===---
Operable voltages 1.5V
RZQ/6 supported? No
RZQ/7 supported? Yes
DLL-Off Mode supported? Yes
Operating temperature range 0-95 degrees C
Refresh Rate in extended temp range 2X
Auto Self-Refresh? Yes
On-Die Thermal Sensor readout? No
Partial Array Self-Refresh? No
Module Thermal Sensor Yes
SDRAM Device Type Standard Monolithic ---=== Physical Characteristics ===---
Module Height 30 mm
Module Thickness 2 mm front, 2 mm back
Module Width 67.6 mm
Module Reference Card F revision 0
Rank 1 Mapping Standard ---=== Manufacturer Data ===---
Module Manufacturer Micron Technology
DRAM Manufacturer Micron Technology
Manufacturing Location Code 0x0F
Manufacturing Date 2011-W23
Assembly Serial Number 0xFB5C7F1A
Part Number 16JSF51264HZ-1G4D1
Revision Code 0x4431

Довольно много данных. Часть показанной информации вычисляется из данных. Например, тайминги на стандартных скоростях (т.е. отсчёты цикла) вычисляются на основе параметров тайминга в наносекундном разрешении. Даже они сохранены как величины, кратные блоку развёртки (time base unit), установленному в другом месте на EEPROM, но это не относится к теме статьи. Данный модуль RAM выдаёт 7-7-7-20 на DDR3-1066, что соответствует стандарту DDR3-1066F JEDEC. Не спрашивайте меня, что такое JEDEC, но он быстрее, чем самый дешёвый DDR3-1066G.

Здесь это 1,5 нс, т.е. Я потратил много времени на подтверждение моего вывода: при попытке ребиннинга памяти единственное важное число — это минимальное время цикла (tCK). 667 МГц.

Давайте посмотрим на исходные данные.

$ i2cdump 9 0x50
No size specified (using byte-data access)
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-9, address 0x50, mode byte
Continue? [Y/n] 0 1 2 3 4 5 6 7 8 9 a b c d e f 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 ?...............
30: 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 ................
50: 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 ................
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 D1D1?,..........
a0: 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 ................

Спецификации говорят, что минимальное время указано по адресу 0x0c. Посмотрим, оно в первой строке (00:), в колонке c. Кстати, его значение тоже 0x0c или 12. Это кратно средней временной базе (MTB), которая представляет собой частное от деления значения в 0x0a на значение в 0x0b (в наносекундах). Здесь 1⁄8 нс. Так что 12 MTB соответствует 1,5 нс.
Чтобы опуститься до DDR3-1066, нам нужно 533 МГц, что составляет 1,875 нс или 15 MTB, или 0x0f. То есть мы хотим написать 0x0f по адресу 0x0c.

CRC первых 116 байт сохраняется в 0x7e-7f. Но подождите, очевидно, есть исправление ошибок. Мне потребовалось удивительно много времени, чтобы найти работоспособный калькулятор CRC. Я посмотрел туда и увидел a4 ae, затем пошёл искать калькулятор для расчёта. Затем узнал, что здесь используется вариант CRC-16/XMODEM, а контрольная сумма на самом деле 0xAEA4. Я попробовал несколько инструментов командной строки, но всё-таки остановился на онлайн-калькуляторе http://crccalc.com/. Следовало заметить её в выдаче decode-dimms. Порядок байтов и всё такое.

Поэтому нужно записать новое минимальное время цикла (0x0f) по адресу 0x0c и новую контрольную сумму в 0x7e как слово.

Теперь я знал, что писать, и наконец осмелился попробовать. Дрожащими руками я набрал y, нажал Enter для окончательного подтверждения и…

$ i2cset 9 0x50 0x0c 0x0f
WARNING! This program can confuse your I2C bus, cause data loss and worse!
DANGEROUS! Writing to a serial EEPROM on a memory DIMM
may render your memory USELESS and make your system UNBOOTABLE!
I will write to device file /dev/i2c-9, chip address 0x50, data address
0x0c, data 0x0f, mode byte.
Continue? [y/N] y
Error: Write failed

Ошибка. Погодите, что?

В какой-то момент я понял, что это может быть вызвано защитой от записи. Будучи педантичным парнем, я начал изучать исходники i2cset, а также соответствующих модулей ядра.

На ней написано 97B, 321 и некоторые другие вещи. Я достал модуль памяти, посмотрел на него и узнал микросхему EEPROM. Я просмотрел таблицу данных и несколько раз внимательно прочитал раздел о защите от записи. Погуглив, я узнал, что это чип SE97B. Защита от записи, вероятно, была постоянной, поэтому я просто решил поискать модуль, у которого нет защиты от записи. С помощью программ я предпринял несколько попыток удаления временной защиты от записи, но неудачно.

Я не думаю, что i2cdetect нормально это делает, но запуск i2cget 9 0x30 <any-address>, вероятно, установит постоянную защиту от записи, которая действительно постоянна. Забавный факт, кстати, заключается в том, что постоянная защита от записи включается записью чего-то на определённый адрес. Я не пробовал этого делать.

EEPROM просто не изменился. Я взял следующий модуль, и там не было никакого сообщения об ошибке.

С третьим модулем наконец-то операция получилась. Я рассчитал CRC и записал его вместе с временем цикла. После загрузки модуля ядра eeprom и запуска decode-dimms модуль выглядел как обычный 4GB PC3-8500. Когда я установил его в MacBook Pro, у меня, наконец, загрузилась система с памятью 8 ГБ.


DDR3 SODIMM после ребиннинга готов к работе в MacBook Pro

До: оригинальный DDR3-1333

0 1 2 3 4 5 6 7 8 9 a b c d e f 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 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 0f 11 45 00 ............??E.
40: 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 ................
60: 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 03 ?.?............?
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 32 59 00 .............2Y.
c0: 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 ................
e0: 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 ................

После: выглядит как DDR3-1066

0 1 2 3 4 5 6 7 8 9 a b c d e f 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 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 0f 11 45 00 ............??E.
40: 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 ................
60: 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 03 ?.?............?
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 32 59 00 .............2Y.
c0: 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 ................
e0: 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 ................

Если сразу не видите разницу, то вы не копались в этих свалках так долго, как я.
Стоит этим заниматься? Финансово, конечно, нет!

Понятия не имею, где именно можно применить эти знания, но я чувствую, что в определённый момент они понадобятся. Но это было весело и я многому научился. И просто само ощущение, что вы можете правильно решить задачу, действительно приятно и даёт уверенность.

1. Моё предположение, что RAM будет работает на данном оборудовании, если оно проходит memtest86, было очевидно неправильным. Тем не менее, даже оглядываясь назад, предположение не кажется глупым. По опыту, не так уж редко встречается странная комбинация аппаратного обеспечения, из-за которой падает стандартный тест. ↑

Я недавно я узнал об использовании I²C в другом проекте. 2. Тем не менее, я действительно счастлив, что теоретически способен на такое! Думаю, что смогу считывать и записывать EEPROM на микроконтроллере Cortex-M с помощью собственной программы, но на практике пайка разъёма будет очень сложной, и написание кода — слишком большая работа, чтобы я этим заинтересовался. ↑


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Теория счастья. Случайности неслучайны

Продолжаю знакомить читателей Хабра с главами из своей книжки «Теория счастья» с подзаголовком «Математические основы законов подлости». Это ещё не изданная научно-популярная книжка, очень неформально рассказывающая о том, как математика позволяет с новой степенью осознанности взглянуть на мир и жизнь ...

Снежинки в стилистике StarWars своими руками (upd. 2018)

Для изготовления снежинок вам потребуется: Файл со схемой.2. 1. Ножницы.4. Принтер (думаю лазерный будет предпочтительней).3. Бумага.5. Скальпель.5. Лично мое мнение — при печати на стандартной офисной бумаге плотностью 80г/м2 становится не очень удобно вырезать (все-таки при складывании бумаги получается толстый ...