[Из песочницы] Downclocking оперативной памяти на MacBook

habr.png

Хочу поделиться своим опытом апгрейда своего MacBook6,1 A1342 (увеличение памяти до 8Гб, установка SSD) и решении ряда проблем связанных с установкой системы на новый диск и борьба с глюками несовместимости RAM.

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


За символическую сумму был куплен с рук MacBook, это первый мой ноутбук этой фирмы, изначально брал чтобы «познакомиться» с продукцией фирмы. Сразу после покупки обнаружилось, что комп сильно тормозной для наших дней, к такому знакомству я был не готов. По совету знакомого рел сделать апгрейд. Выяснил что внутри SATA диск 2.5» и 2 планки DDR3 204pin SO-DIMM 1066MHz, официально поддерживает максимум до 4Gb в один слот. В магазине был выбран SSD диск на 250Gb (тут с выбором проблем нет: любой SATA 2.5» подойдет, ассортимент широкий на любой вкус).

А вот с RAM не все так просто. Официально эта модель макбука поддерживает оперативу 1066MHz, в наличии такой не оказалось, а под заказ одна планка стоила около 4000 руб. В тоже время в наличии была 4Gb 1600MHz по цене около 2000 руб. Взял более быструю, из расчета на обратную совместимость. Не завелось. В магазине удалось подобрать один модуль памяти, с которым система стартовала (AMD R334G1339S1S) и я счастливый пошел домой, не забыв заказать второй такой же. А чтоб второй слот не пустовал, временно включил туда родную планку 1Gb.

Надо сказать, что разочаровавшись в медленной macOS, я установил Windows 7 на весь раздел и не сделал бэкап системы — не повторяйте моей ошибки!

На этом лирика заканчивается и начинаются танцы с бубном.


В моей деревне Mac есть у двух человек: первый у меня, а второй у того одноглазого бандита, который держит в страхе всю деревню. Из подручных средств: флешка 8Gb, второй ноутбук с Windows 7 на борту, выделенная линия интернет.

В интернете много статей о том, как сделать загрузочную флешку macOS непосредственно в macOS. Как сделать загрузочную флешку с macOS High Sierra из под Windows не очень много и они все оказываются далеко внизу в выдаче после способов как это сделать в macOS. Я уже было стал искать образы флешек в формате .img .iso .bin и прочих, но увы и ах! Может где-то на заблокированных торрент-трекерах они и есть, но я не нашел. Зато нашел утилиту BDU (Boot Disk Utility), с помощью которой можно скачать необходимые файлы прямо с AppStore и записать на флешку. Программа простая, на официальном сайте есть подробная инструкция с картинками, по-этому останавливаться на этом этапе не буду. Скажу лишь, что разбивать флешку на 2 раздела и качать Clover нет необходимости, достаточно скачать RecoveryHD образ и записать его в раздел флешки.

Далее грузимся с флешки (при старте жмем Alt и держим до появления меню). В дисковой утилите форматируем диск (я выбрал GUID, APFS). Подключаемся к интернету по WiFi или проводом и запускаем установку. Если все хорошо, то дальше система сама скачается с интернета и установиться на компьютер.


Вторая планка пришла довольно быстро, не успел я насладиться новым SSD диском и 4+1 Gb RAM. Поставил оперативку, в About This Mac отобразилось полные 8Gb и я принялся мучать систему тяжелыми задачами. Примерно 1–2 раза в день комп стал перезагружаться. Ошибки типа kernel_panic во всех подряд приложениях от Xcode до простого TextEdit’а. Дошло до того, что перестали скачиваться приложения из AppStore. Первая мысль — оперативка битая. Гонял Memtest — все в порядке. Повторная установка с созданной в BDU флешки кончается крахом (verified error, checksum error и другие ошибки). Пришлось далеко ходить за offline установочной флешкой созданной непосредственно в macOS (из под Windows такую сложно сделать). Но даже это не спасло.

Обратил внимание, что память работает на частоте 1333MHz. Т.к. BIOS в маке отсутствует, то пришлось понижать частоту включением параллельно родной планки 1Gb 1066 MHz. И это помогло! Система не сбоит, из AppStore все качается нормально. Но как же тогда вторая планка?

Перерыв весь интернет, нашел 2 способа решения проблемы:

  1. Обновление EFI от аналогичного MacBookPro, при этом не факт что не умрет совсем и в результате будет в About This Mac писать что это Pro;
  2. Изменить максимально допустимую частоту работы памяти в SPD блоке самой памяти в одной из планок, тогда EFI будет выбирать ее автоматически.


Я выбрал второй вариант, т.к. риск убить одну планку из двух для меня дешевле. Плюс возможные проблемы в будущем из-за неверной идентификации платы системой. Пусть EFI обновляет сама Apple. Для даунклокинга потребуется живой диск с Linux (я использовал установочный диск Ubuntu 16.04.2)

План действий:

1. Снять dump из SPD EEPROM памяти;
2. Найти и уменьшить частоту шины с 1333MHz до 1066MHz;
3. Пересчитать CRC;
4. Записать полученные значения обратно в EEPROM.

Если у Вас есть лишние 16$, то можете просто купить Thaiphoon Burner и сделать все операции в нем. Если нет, то прокачиваем прямоту рук. Поехали!

Снимаем дамп

Грузимся в Ubuntu, запускаем терминал, далее все будем делать под рутом. Устанавливаем i2c-tools, подгружаем драйвера:

sudo -I
#add-apt-repository universe
#apt-get update
#apt-get -y install i2c-tools
#modprobe eeprom
#modprobe i2c-smbus
#modprobe i2c-dev
#modprobe i2c-nforce2


Посмотрим какие шины у нас есть:

#i2cdetect -l
i2c-3   i2c             nvkm-0000:02:00.0-aux-0008              I2C adapter
i2c-1   i2c             nvkm-0000:02:00.0-bus-0002              I2C adapter
i2c-8   smbus           SMBus nForce2 adapter at 2140           SMBus adapter
i2c-6   i2c             nvkm-0000:02:00.0-aux-000b              I2C adapter
i2c-4   i2c             nvkm-0000:02:00.0-aux-0009              I2C adapter
i2c-2   i2c             nvkm-0000:02:00.0-bus-0003              I2C adapter
i2c-0   i2c             nvkm-0000:02:00.0-bus-0000              I2C adapter
i2c-9   smbus           SMBus nForce2 adapter at 2100           SMBus adapter
i2c-7   i2c             0000:02:00.0                            I2C adapter
i2c-5   i2c             nvkm-0000:02:00.0-aux-000a              I2C adapter


Подскажите в комментариях как в этом списке однозначно найти где висит RAM? Я предварительно использовал бесплатную версию Thaiphoon Burner, по-этому знаю куда иду.

Итак, на 8й шине висит SMBus nForce2 adapter at 2140. Посмотрим что внутри:

#i2cdetect -y 8
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: UU UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --


Здесь UU UU это две мои планки одна из них на 1Gb, другая на 4Gb. Адреса 0×50 и 0×51. Какая из них где, можно определить по дампу каждой, опираясь на серийный номер, например, или год выпуска. Я же уже заранее посмотрел эту информацию в Thaiphoon Burner, по-этому сразу смотрим устройство по адресу 0×51. Сделаем дамп памяти первых 256 байт — это и есть SPD EEPROM:

#i2cdump -f -r 0x00-0xff -y 8 0x51 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 92 11 0b 03 03 19 00 09 03 52 01 08 0c 00 3c 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 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 01 44 00 00 00 00 00 00 4f 5d    .....??D......O]
80: 52 33 33 34 47 31 33 33 39 53 31 53 00 00 00 00    R334G1339S1S....
90: 00 00 00 00 80 01 00 00 00 00 00 00 00 00 00 00    ....??..........
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
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    ................


Частота шины

Далее все делаем в уме\блокноте, но ни в коем случае не пишем в EEPROM!
Полученный дамп я аккуратно перенес в текстовый документ. Почитав JEDEC Standard No. 21-C узнаем, что искомый параметр находится в 12-м байте (т.е. со смещением 0×0C), а частоте 1066MHz (на самом деле в документации пишется вдвое меньшая частота 533MHz) соответствует значение 15 (т.е. 0×0F). исправляем в блокнотике и идем дальше.

Контрольная сумма CRC

Тут немного сложнее, CRC считается либо для первых 126 байтов, либо для 117 байтов. Определяется это старшим битом первого байта. У меня это значение 0×92, старший бит = 1, что соответствует CRC Coverege 0–116. Само значение CRC вычисляется по стандартной формуле CRC-CCIT 16bit polynomial 0×1021. Я использовал онлайн-калькулятор CRC, где прямо текстом все прекрасно вставляется и считается. Важно учесть, что байты CRC после подсчета записываются в обратном порядке в EEPROM в 126й и 127й байты. В моем случае онлайн калькулятор насчитал CRC 0×5047, в EEPROM запишу 0×47, затем 0×50.

Запись в EEPROM

Прежде чем продолжить, стоит еще раз все перепроверить: почитать JEDEC, оценить риски, попробовать посчитать CRC уже рабочих модулей, чтобы отточить навык. В случае ошибки, память умрет! Можно конечно заморочиться, подключить к программатору и восстановить SPD из backup’а (Вы ведь его сделали?). Тогда продолжим.

В моем случае нужно записать (адрес=значение):

0×0C = 0×0F (12й байт частота)
0×7E = 0×47 (126й байт CRC.2)
0×7F = 0×50 (127й байт CRC.1)

#i2cset -f -y 8 0x51 0x0C 0x0F
#i2cset -f -y 8 0x51 0x7E 0x47
#i2cset -f -y 8 0x51 0x7F 0x50


Проверяем, записались ли значения:

#i2cdump -f -r 0x00-0xff -y 8 0x51 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 92 11 0b 03 03 19 00 09 03 52 01 08 0f 00 3c 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 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 01 44 00 00 00 00 00 00 47 50    .....??D......GP
80: 52 33 33 34 47 31 33 33 39 53 31 53 00 00 00 00    R334G1339S1S....
90: 00 00 00 00 80 01 00 00 00 00 00 00 00 00 00 00    ....??..........
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
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    ................


Как видно, все записалось верно. На всякий случай перепроверяем и перезагружаемся. Если компьютер включился и вся память доступна — поздравляю! Убираем родную планку 1Gb, ставим вторую (не прошитую) и проверяем частоту памяти — 1066MHz.

Если память не прошилась, значит стоит Write Protect. Можно попробовать разблокировать утилитой Thaiphoon Burner, либо напаивавшем резистора на одну из ножек памяти (тема отдельной статьи), либо попробовав прошить другую планку.

Надеюсь эта статья будет кому-либо полезна. Писал в основном для себя, чтобы снова не искать всю информацию в разных местах.

При написании были использованы материалы

© Habrahabr.ru