MemForge2: загрузочная флешка, которая за минуту говорит — какую планку памяти менять

от автора

Сегодня собирал HP EliteDesk 8300, четыре планки DDR3 по 2 ГБ. При первой загрузке — синий экран Windows. Стандартный сценарий: сейчас полчаса вытаскивать планки по одной, перезагружаться, выяснять какая сбойная. «Танцы с бубнами», которые каждый сервисник делал тысячу раз.

Потом вспомнил, что у меня есть собственный инструмент ровно для этого (в разаботке). Воткнул флешку, прогон, минута — на экране большими буквами: REPLACE DIMM1, confidence HIGH. Чтобы убедиться что программа не «запоминает» слот а реально находит планку, переставил её в DIMM4. Прогон повторно — нашла её и в DIMM4, тот же серийник из SPD. Замена планки — BSOD больше нет.

Я работаю на сборке ПК — и новых, и б/у. На б/у это типичная ситуация: всё собрано, провода уложены, включаешь — синий экран на загрузке. Метод исключения работает, но это перезагрузка за перезагрузкой, глубокий вдох перед каждой, час твоего времени уходит на то, что должна была бы решить минута. Мне нужен был инструмент, который сразу показывает где проблема — без часовых прогонов и без танцев со свапами планок. Готового с такой комбинацией возможностей я не нашёл, поэтому собрал свой.

Сразу честно про авторство. Я не программист. Я сборщик. Код MemForge2 писал не я — его писал Claude (LLM от Anthropic) под мою постановку задачи. Я приходил с пониманием предметной области («нужно SPD через SMBus, серийник для гарантии, MCA-снимок до/после, контекст в момент ошибки»), описывал что должна делать программа на конкретных кейсах со своей сборки, гонял каждую версию на реальном железе, ловил баги, возвращался с дампами и описаниями поведения. Claude писал C, разбирался с UEFI-API, MSR-ами, SMBus-протоколом, SPD JEDEC-стандартом.

Это не «AI сделал всё сам» и не «я сделал всё сам с помощью AI». Это эксперимент в том, насколько далеко можно зайти с AI-assisted разработкой, когда у тебя глубокое понимание задачи и доступ к реальному железу для тестирования, но нет навыков системного программирования. Раздел «баги, которые ловил при тестировании» ниже — это и есть моя реальная работа в этом проекте: empirical validation на разном железе, которое модель сама воспроизвести не может. На текущей стадии MemForge2 прогонялся на разных конфигурациях — Intel, AMD Ryzen, HP business-машины, разные разрешения экрана — именно из этих прогонов вылезли баги, описанные в разделе ниже. Подтверждённое срабатывание на реально сбойной планке памяти с успешной заменой и исчезновением BSOD — пока один HP 8300. Насколько эта схема масштабируется дальше, увидим по мере того как читатели будут присылать свои кейсы.

Этот текст — про MemForge2, UEFI-приложение, чтобы диагностика памяти занимала минуту, а не полчаса. Открытый код, готовый бинарник, флешка на FAT32 — больше ничего не нужно.

GitHub

TL;DR

Загружается с USB до запуска ОС, прогоняет 14 параллельных тестов памяти на всех ядрах CPU, читает SPD напрямую через SMBus, снимает MCA-банки до и после прогона. При обнаружении ошибок выдаёт конкретно: какой DIMM-слот менять, серийник модуля для гарантии, и что именно сломано (stuck-bit, дефектный bank, Row Hammer-уязвимость, термальная маржинальность).

Что есть сверху обычного memtest:

  • Контекст в момент каждой ошибки — temp/Watt/throttle/VID на тот самый миллисекундный таймстамп, когда упал бит. Отличает «холодный stuck cell» от «ошибки только при 85°C+».

  • Cold/warm boot delta через UEFI NVRAM — после прогона сохраняет 96 байт состояния, на следующей загрузке показывает дельту: «+3 новые ошибки, +6°C по сравнению с прошлым прогоном».

  • Marathon mode 1-24 часа — для интермиттент-проблем, которые на 30-минутном тесте не вылезают, а у клиента раз в неделю BSOD.

  • report.json + memforge2.log на флешку — после прогона забираешь флешку и спокойно разбираешься, не нужно срочно фотографировать экран.

Открытый исходный код (gnu-efi), C, один файл, ~9000 строк. Бинарник 285 КБ в Releases.

Honest validation status: программа прогонялась на разных платформах — Intel, AMD Ryzen, разные поколения памяти, разные разрешения экрана. Подтверждённое нахождение реально сбойной планки с успешной заменой — пока один HP 8300. На большем количестве заведомо сбойных сэмплов не валидирован — если у вас такие есть, фидбек в Issues очень нужен.

Почему свап-тестирование съедает время

Стандартный workflow при подозрении на память:

  1. Запустил memtest86+, увидел красное «error at 0xDEADBEEF»

  2. Окей, какая из четырёх планок? Адрес ничего не говорит

  3. Вынул планку 1, перезагрузка, тест, снова ошибки — не она

  4. Вынул планку 2, перезагрузка, тест, чисто — она? Или интермиттент?

  5. Поставил обратно, для надёжности перебрал слоты ещё раз

  6. Полчаса-час потрачено на одну только локализацию

memtest86+ — отличный тест памяти, но это именно тест памяти. На вопрос «какую планку нести продавцу» он не отвечает. PassMark MemTest86 (бесплатная версия) — то же самое, плюс не поднимает CPU в turbo P-state, тесты идут на базовой частоте, термальная нагрузка ниже (PassMark это на своём форуме открыто признают). HCI Memtest, Karhu, TM5 — все требуют работающей Windows, а если машина не догружается до десктопа, они бесполезны.

И ни один из этих инструментов не оставляет на флешке структурированного лога, который можно потом спокойно разобрать.

Что хотелось:

  • Загрузка с флешки до ОС, чтобы Windows-драйверы и антивирусы не были переменной

  • Прямой ответ: «вот этот слот, вот серийник, идите за заменой»

  • Серийник из самого модуля (SPD через SMBus), а не из SMBIOS, где он часто пустой

  • Снимок MCA-банков до/после — ловит ECC-ошибки, которые контроллер тихо исправил и pattern-тесты их по определению не видят

  • Снимок температуры/Watt/throttle в момент каждой ошибки — отличить аппаратный дефект от термальной маржи

  • Структурированный JSON-лог на флешке для последующего разбора

  • Сравнение прогонов между перезагрузками — увидеть стало хуже или лучше после ребола/очистки/замены пасты

Как пользоваться

Пять минут от флешки до вердикта:

  1. Любая FAT32 USB-флешка

  2. Скачать MemForge2.efi из Releases на GitHub

  3. Положить в \EFI\BOOT\loader.efi на флешке

  4. (Опционально) quantai.ini в корень флешки — для настройки длительности и опций

  5. Загрузиться с флешки, ENTER — полный тест, [2] — быстрый

Про Secure Boot. На современных HP/Dell/Lenovo business-моделях Secure Boot включён по умолчанию, и неподписанный .efi загрузчик просто не стартует. Два варианта:

  • Отключить Secure Boot в BIOS (быстро, но иногда требует Admin Password)

  • Обернуть MemForge2.efi в PreLoader.efi от Linux Foundation с enrollment через HashTool.efi — это позволяет загрузиться без отключения Secure Boot

Подробные инструкции по настройке BIOS для разных вендоров — в BIOS_SETUP.md в репозитории.

Длительность прогона. Быстрый — пара минут, ловит явные дефекты (stuck-bit, broken bank), пропускает термально-маржинальные. Полный — 15-30 минут в зависимости от объёма памяти. Marathon — 1-24 часа, для случаев «BSOD у клиента раз в неделю», ставится через MarathonHours=N в quantai.ini.

Что показывает экран при ошибке

Скриншот вердикта на HP 8300

Скриншот вердикта на HP 8300

Что важно прочитать:

  • REPLACE: DIMMx — слот для замены, как он называется на материнке (DIMM1, DIMM_A1, ChannelA-DIMM0)

  • Confidence: HIGH/MEDIUM/LOW — насколько уверена программа. HIGH = чёткий stuck-bit или плотный кластер ошибок. LOW = редкие случайные ошибки, может быть термальный margin, может быть электромагнитные наводки

  • DIMM info (for warranty) — Manufacturer / Part number / Serial из SPD модуля. Это копируешь продавцу для гарантийной замены

  • What was detected — что именно нашли: stuck-bit (физический дефект ячейки), bank-кластер (дефектная зона на чипе), термальная маржа (ошибки только при 85°C+), Row Hammer-уязвимость

Для технического разбора есть [D] — открывает детальный экран с полной таблицей тестов, per-error записями (адрес, DIMM, DRAM-координаты), diff MCA-банков, SPD-таймингами и трендом пропускной способности.

Замечание по скриншоту: он сделан на v0.3 до фикса DDR3 SPD-парсинга (см. раздел «факапы»), поэтому chip U3 (x16) — это ошибочная per-chip маркировка для Samsung 1Rx8 модуля. На v0.4 показывало бы chip U5 bit 4 (x8). Слот DIMM1 и серийник были определены корректно — планка заменилась успешно.

Что остаётся на флешке после прогона

После завершения теста рядом с loader.efi на флешке появляются:

  • memforge2.log — человекочитаемый лог с timestamps, результатом каждого теста, полным SPD по каждой планке (включая тайминги CL-tRCD-tRP-tRAS-tRFC), diff MCA-банков, всеми per-error записями с environmental snapshot, трендом BW по 1-минутным buckets, per-stride MB/s, SMBus signal integrity отчётом.

  • report.json — те же данные в структурированном виде. Каждая запись об ошибке несёт at: {t_ms, temp_c, pkg_w, throttle, vid_mv}. Удобно для последующего парсинга — можно скормить в скрипт, в нейросеть для анализа, или просто открыть в любом JSON-вьювере.

Это важная часть workflow: на самой машине ремонтник видит вердикт на экране и принимает решение «менять / не менять». Но если хочется потом разобраться спокойно — забираешь флешку и читаешь лог на нормальном компьютере. Не надо срочно фотографировать экран в три ракурса.

Cold/warm boot delta. После каждого прогона программа сохраняет 96 байт сводки в UEFI NVRAM. На следующей загрузке показывает дельту по сравнению с прошлым прогоном:

⚠ +3 new errors since last run⚠ temperature rose 6°C — check airflow / paste✓ BW peak unchanged (within 2%)

Это даёт ответ на вопросы вида «после очистки и замены пасты стало лучше?», «после переобжима ребол держится?», «после переустановки планки в другой слот ошибки тех же или новые?». Без отдельного бумажного журнала и без необходимости помнить «было 7 ошибок или 9?». Для сервиса с потоком — экономит реально много мелкой когнитивной нагрузки.

Реальный кейс

Сборка б/у HP 8300, четыре планки DDR3 по 2 ГБ. При первой загрузке — синий экран Windows. Прогон MemForge2: 54 секунды, 396 ошибок, вердикт DIMM1, серийник Samsung M378B5773CH0-CK0 (это и есть скриншот в начале статьи). Чтобы убедиться, что программа не «запоминает» слот а реально находит физический модуль, переставил эту планку в DIMM4. Прогон повторно — нашла её в DIMM4, серийник тот же. Это подтверждает, что маппинг адрес→слот через SMBIOS Type 20 работает корректно, а не «зашит» в код. После замены планки машина собралась и работает.

Это первый подтверждённый случай нахождения реально сбойной памяти с заменой и исчезновением BSOD. Инструмент прогонялся и на других машинах со сборки — там память была исправна, программа корректно показывала чисто. Реальная статистика по разным платформам и типам сбоев соберётся когда инструмент пройдёт через руки многих людей.

Что внутри (для тех кому интересно как)

Один файл MemForge2.src.c, gnu-efi + mingw-w64, ~9000 строк. Сознательно один файл — UEFI-приложение проще читать и собирать без 30 разнесённых модулей.

14 параллельных тестов на всех ядрах через EFI MP Services

#

Тест

Время

Что ловит

1

AVX2 Sustained

~10 с

VRM / iMC при сустейн FMA нагрузке

2

TRRespass

~60 с

8-aggressor Row Hammer с bank rotation (Frigo et al., USENIX Sec 2020)

3

Cache-Eviction

~10 с

DRAM bus errors через CLFLUSH storm

4

March-C-

~2 с

6-фазный JEDEC March (van de Goor 1997), 92% покрытие fault models

5

Thermal Soak

3 мин

Догрев до steady-state — ошибки, которые только при горячей системе

6

BW Soak

5 мин

Сустейн DRAM bandwidth (memtest86+ analog)

7

March-RAW

~3 с

Read-after-write coupling faults

8

Butterfly

~5 с

Cell crosstalk (checkerboard + neighbour flip)

9

Address Pattern

~5 с

Address-line faults

10

VRM Square-Wave

~10 с

VRM transient response (AVX2 burst/idle 10 Гц)

11

Random Pattern

~6 с

xorshift64, 4 паттерна

12

Bit Fade Extended

~8 мин

DRAM retention: write → wait → verify

13

L3 Cache Stress

~10 с

Резидентный workload в L3 — ловит L3-cell faults

14

Stride BW

~12 с

Sweep 64B/1KB/4KB/64KB — TLB / set-conflict / каналы

Из менее очевидного:

L3 Cache Stress. Все остальные тесты делают CLFLUSH между write и verify, данные «пробегают» через L3 насквозь, и L3-клетки не наблюдаются. Этот тест держит 1 MB working set резидентным в L3 и делает RMW цикл ~10 с — ловит L3-cell faults, которые DRAM-only тесты пропускают и которые часто проявляются как silent ECC fires в MCA bank 1.

Stride BW. Per-stride MB/s. Drop на одном stride (а не пропорциональный по всем) — диагностический сигнал TLB shootdown / cache set-conflict / channel interleave bug. Drop на всех — просто горячая система.

HWP / CPPC2 lift — CPU реально в turbo во время тестов

На Intel программируется HWP (IA32_HWP_REQUEST per logical core) и поднимаются package power limits PL1/PL2. На AMD — CPPC2. Эффект: CPU реально работает на boost-частотах во время прогона, термальная нагрузка соответствует реальной работе под нагрузкой. PassMark MemTest86 (бесплатная версия) этого не делает — у них на форуме это прямо признаётся.

Зачем это нужно: ошибки памяти, которые проявляются только под полной термальной нагрузкой, на base-frequency прогоне не вылезают, и инструмент даёт false negative.

SPD через SMBus

Intel SMBus host на PCI 0:1F.4 (BAR4), AMD FCH SMBus на 0:14.0 (PCI offset 0x90 с fallback 0xB00). Протокол PIIX4-совместимый, byte-read:

static int smbus_byte_read(UINT8 addr7, UINT8 cmd_offset, UINT8 *out) {    UINT16 base = g_smbus_io_base;    io_outb(base + 0x00, 0xFF);              // clear sticky status    io_outb(base + 0x04, (addr7 << 1) | 1);  // slave addr | READ    io_outb(base + 0x03, cmd_offset);    io_outb(base + 0x02, (0x2 << 2) | (1 << 6));  // BYTE_DATA + START    UINT8 sts = smbus_wait();    if ((sts & 0x1E) != 0x02) return 0;      // INTR без error bits    *out = io_inb(base + 0x05);    return 1;}

DIMM-адреса 0x50..0x57. DDR4 SPD двух-страничный — нужны page-select команды (0x36/0x37) для bytes ≥ 256. DDR5 — отдельный SPD5118 hub, читаются device-info MRs и SMBus PEC error counter.

Вытягиваются: серийник, manufacturing date, JEDEC manufacturer ID, полный набор первичных таймингов (CL / tRCD / tRP / tRAS / tRFC / tCK). Этого нет в SMBIOS Type 17.

SMBus signal integrity probe. Дополнительно делается 16 повторных чтений одного SPD-байта на каждый слот; mismatches или NAKs флагуются как I²C SI warning. Ловит проблемы шины, которые иначе сводят с ума при попытке диагностики.

5 механизмов локализации ошибки

Когда тест ловит ошибку, программа применяет пять разных подходов и сводит их в единый вердикт:

  1. DIMM slot через SMBIOS Type 20 (Memory Device Mapped Address). Связывает диапазоны физических адресов с handle устройства Type 17, у которого есть locator — имя слота как на материнке.

  2. Per-chip stuck-bit mapping. chip_idx = bit_pos / device_width + 1 на основе device_width из SPD.

  3. Stuck-bit detection через XOR-mask repetition. Если один и тот же xor_mask повторяется 5+ раз в разных адресах и в маске единственный бит — это stuck-bit, физический дефект ячейки.

  4. Stuck-row / stuck-bank detection через DRAM-coord heuristic. Из физического адреса декодируется приблизительная row/bank/bank-group, кластеры ошибок в одних координатах — дефектная зона на чипе.

  5. 1-GB histogram of error addresses. Распределение ошибок по 1-гигабайтным регионам — для отладки interleave/channel проблем.

Вердикт собирается на основе пересечения этих сигналов. Один stuck-bit + кластер в одном bank + всё в адресах одного слота → confidence HIGH. Редкие случайные ошибки без кластеризации → confidence LOW.

Оговорка по chip U-номеру. «U5» в выводе — это индекс чипа по позиции бита, не гарантированно совпадает с silkscreen-маркировкой на PCB (производитель может пронумеровать чипы в любом порядке, особенно если они с двух сторон платы). Для ребола техник на верстаке найдёт чип по DQ-линиям, но рассчитывать что U5 на экране = U5 на текстолите нельзя.

Per-DIMM isolation

TestOnlyDimm=N в quantai.ini ограничивает тестовый буфер диапазоном одного DIMM (через AllocateAddress UEFI плюс SMBIOS Type 20). Идеальная изоляция на non-interleaved памяти; на dual-channel desktop ограничивает до пары каналов.

MCA snapshot

Банки MCi_STATUS (MSR 0x401 + 4·i), MCi_ADDR (0x402 + 4·i). Если контроллер сам исправил single-bit ECC error — это ложится в банк, pattern-тесты этого не видят, потому что в данных уже лежит корректное значение.

static void mca_snapshot(UINT64 *out) {    for (UINT32 i = 0; i < g_mca_bank_count; i++) {        out[i] = rdmsr_safe(0x401 + 4 * i);    }}

Дифф до и после прогона. Новые VAL биты (bit 63) = что-то произошло. Если ADDRV (bit 58) валиден — раскручиваем адрес в DIMM-slot через тот же Type 20.

Контекст в момент ошибки

Каждая ошибка сохраняет timestamp, температуру, package power, throttle count, VID:

g_err_records[idx].t_ms       = ms_now() - g_run_start_ms;g_err_records[idx].temp_c     = g_max_temp_c;g_err_records[idx].pkg_watt   = g_pkg_power_w;g_err_records[idx].throttle_cnt = g_throttle_total;g_err_records[idx].vid_mv     = g_pkg_vid_mv;

В логе:

[ERR] T=AVX2 Sustained Core=3 Addr=0x3A8F00120 ...[ERR]   when: t+182s temp=87°C W=134 throttle=12 VID=1.235V

Критично для термально-маржинальных случаев. Stuck cell упадёт холодным — аппаратный дефект, менять. Если ошибки начинаются только при temp ≥ 85°C — это термальная маржа контроллера или планки, решается охлаждением, а не заменой.

Bandwidth degradation trend

Прогон делится на 1-минутные buckets, в каждом считается достигнутая пропускная способность памяти. Первый квартиль buckets сравнивается с последним:

  • Drop > 5% — флаг mild degradation (медленный thermal throttle, IMC retry, неровный контакт)

  • Drop > 15% — флаг severe degradation (планка тепловит, контроллер уходит в защиту)

Ловит ситуации, когда pattern-тесты ничего не нашли, но память деградирует под продолжительной нагрузкой. Часто это первый признак умирающей планки до того, как появятся явные битовые ошибки.

Marathon mode

MarathonHours=N (1-24) в quantai.ini. Тесты крутятся N часов с multipass iterator wrap — каждый цикл покрывает свежие (region, offset) пары, чтобы не долбить одни и те же ячейки.

Зачем нужно: интермиттент-проблемы, которые на 30-минутном прогоне не вылезают, а у пользователя BSOD раз в неделю. Marathon моделирует именно эту длительную нагрузку и часто ловит то, что короткие тесты пропускают.

Cold/warm boot delta

После каждого прогона 96 байт сводки сохраняются в UEFI NVRAM. На следующей загрузке программа читает прошлую сводку и считает дельту: change in error count, peak temperature, BW peak, throttle events. Выводит explicit warnings: «⚠ 3 new errors since last run», «⚠ temp rose 6°C — check airflow».

Это превращает каждый последующий прогон в сравнение с базой, а не в изолированную точку. Для сценариев типа «после чистки», «после ребола», «после замены пасты», «после переустановки планки» — мгновенно видно стало ли лучше.

Баги, которые ловил при тестировании на реальном железе

Если коротко обобщить роли: Claude писал код, я гонял его на машинах со сборки и приносил обратно то, что не работало. Вот основные кейсы.

rdmsr_safe оказался не safe (AMD Ryzen)

static inline UINT64 rdmsr_safe(UINT32 reg) {    UINT32 lo, hi;    __asm__ __volatile__("rdmsr" : "=a"(lo), "=d"(hi) : "c"(reg));    return ((UINT64)hi << 32) | lo;}

«Safe» только по названию. Реально не ловит #GP fault — если MSR не поддерживается, процессор бросает exception, UEFI default handler не настроен на возврат, машина зависает.

Вылезло на первом прогоне на AMD Ryzen при чтении MSR_PLATFORM_INFO (0xCE, Intel-only регистр). Программа доходила до строки [PERF] BSP: HWP unavailable и замораживала систему намертво. Я этого не предвидел, потому что не знал что MSR-ы бывают вендор-специфичными — пришёл с дампом «вот тут виснет на Ryzen», после чего Intel-специфичный блок обернули в if (g_cpu_vendor == CPU_INTEL). Базовый урок кросс-вендорной x86 разработки, который я как непрограммист просто не знал.

DDR3 SPD — читались чужие байты

В первой версии код читал Module Organization из SPD byte 12 для всех классов памяти — это правильно для DDR4, но у DDR3 (JESD79-3) byte 12 — это Module Nominal Voltage, совершенно другое поле. Реальная организация модуля у DDR3 в byte 7.

Эффект: на Samsung M378B5773CH0-CK0 (1Rx8) программа показывала x16 организацию и считала chip U3. Должно было быть x8 и U5. Заметил когда стал сверять вывод с datasheet Samsung — цифры не сходились. Замена планки в исходном кейсе тем не менее сработала, потому что слот определялся правильно через SMBIOS Type 20, но per-chip номер был ошибочным. Это и есть скриншот в начале статьи.

Починили, расписав параметры по DDR-поколениям:

UINT8 b_org = 0, b_bw = 0;if (d->spd_size_class == 3 && n_bytes >= 9) {    b_org = buf[7];  b_bw = buf[8];           // DDR3} else if ((d->spd_size_class == 4 || d->spd_size_class == 5)           && n_bytes >= 14) {    b_org = buf[12]; b_bw = buf[13];          // DDR4/5}

Аналогично для DDR3 манифактур / серийник / дата выпуска оказались в bytes 117-125 (DDR4 кладёт их в 320-328). До этого DDR3 модули показывались без серийника — пользы для гарантии нет.

HP firmware вырубает USB-клавиатуру

После завершения теста экран summary ждёт нажатия ESC / M. Стандартный код:

uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &idx);

На некоторых HP business EFI этот блокирующий wait через несколько секунд деактивирует USB-клавиатуру — firmware решает, что раз никто не опрашивает активно, можно прекратить polling. Я столкнулся с этим когда не мог выйти со screen вердикта и пришлось дёргать питание. Принёс описание поведения, появился фикс: timer event 200 мс плюс ConIn->WaitForKey в массиве событий. На timer-тике крутимся обратно в WaitForEvent — это заставляет firmware продолжать опрашивать USB. На firmware где проблемы нет — никаких побочных эффектов.

Layout overflow на FullHD

После добавления тестов 13 и 14 (стало 14 вместо 12) на 1920×1080 cores panel ушёл за нижний край экрана. CPU07/CPU08 не были видны, на CPU04 рендер наезжал на progress bar. Заметил при первом прогоне на FullHD машине — некоторые тесты на экране были, но мониторинг ядер отрезался.

Фикс — в layout-калькуляторе сначала пробуем 1-колоночные карточки тестов; если total height > screen, переключаемся на 2-колоночные (7×2). Решает 14 тестов на 1080p, не ломает узкие 1366×768 которые и так на 2-col.

Урок (мой, как тестировщика): после изменения количества тестов или размеров шрифта обязательно прогонять layout на основных разрешениях.

Чего пока НЕТ — честный disclosure

  • DDR5 on-die ECC counters (MR48-51 внутри DRAM die): требуется Mode Register Read через iMC mailbox, chipset-specific, не публикуется Intel/AMD полностью. Пока умею только читать SPD5 Hub registers (PEC counter, device info) через стандартный SMBus.

  • AMD VID: для Intel читаю IA32_PERF_STATUS bits[47:32]. На AMD требуется per-family декодирование MSR_PSTATE_DEF (Zen1/2/3/4 имеют разные поля). Не реализовано.

  • DRAM coordinates — эвристика: decode_dram_coords даёт приблизительные ~bank-group / ~bank / ~row / ~col через generic layout. На consumer Intel/AMD совпадает достаточно для cluster detection. На серверных Sapphire Rapids+ / EPYC Genoa+ iMC использует другую interleave-функцию — координаты будут смещены, но cluster detection всё равно работает (cluster — это «много ошибок в одной точке», не «точная точка X»).

  • Chip U-номер — приблизительный: см. оговорку выше. Точный slot и серийник — точные, U-номер на silkscreen может быть другим.

  • HP Sure Start / Dell Trusted Boot: на некоторых business-моделях firmware блокирует SMBus probing — не получаем SPD (серийник, тайминги). DIMM-slot через SMBIOS остаётся.

  • Server SMBus controllers (Sapphire Rapids и новее): поддерживаю common Intel ICH + AMD FCH. На новых серверных платформах SMBus может быть другой контроллер — не тестировал.

  • Статистика по типам сбоев: один подтверждённый кейс находки сбойной памяти с заменой. Функциональные прогоны (без обнаружения дефектов) проводились на нескольких платформах — Intel, AMD Ryzen, разные разрешения дисплея. На большем количестве заведомо сбойных сэмплов не валидирован — фидбек в Issues максимально приветствуется.

  • Версия — не финальная. Конфигураций ПК слишком много, чтобы я мог покрыть все самостоятельно. По мере того как ко мне на сборку приходят разные машины — будут вылезать новые edge cases и я их буду чинить. Если ваша конфигурация не описана и инструмент ведёт себя странно — это ожидаемо на текущей стадии, открывайте issue с dump’ом, разбираться буду.

Откуда брать

  • GitHub: https://github.com/Paradoxdov/memforge

  • Готовый бинарник: Releases v0.4 — MemForge2.efi 285 КБ. Собирать самому не обязательно.

  • Настройка BIOS под разные вендоры: BIOS_SETUP.md в репозитории.

  • Issues / Discussions включены — особенно важны кейсы с заведомо сбойной памятью.

Развёртывание:

  1. FAT32 USB

  2. MemForge2.efi\EFI\BOOT\loader.efi

  3. quantai.ini → корень USB

  4. Boot from USB, ENTER — полный тест, [2] — быстрый

quantai.ini имеет несколько ручек:

[Run]Passes=0            ; 0 = auto from RAM sizeMultiPass=1         ; ротировать буфер по всем регионам RAMMaxCores=0          ; 0 = все ядраEnableAVX=1;BufferMB=1024      ; auto-scaled by RAM size;BitFadeSeconds=60  ; DDR4 default; DDR5 auto-bumped to 120;BitFadeEveryPass=0 ; ретеншн только на первом проходе по умолчанию;TestOnlyDimm=0     ; 1..N — изолировать конкретную планку;MarathonHours=0    ; 0 = off, 1..24 — длинный прогон для интермиттент проблем[Meta]Version=4.6Language=ru         ; ru или en — интерфейс программы[Display];Width=1920         ; manual GOP mode override;Height=1080;FontScale=0        ; 0=auto, 1=1×, 2=2× для 4K

Лицензия — открытая (см. файл LICENSE в репо), форки и контрибы приветствуются.

Ссылки

[1] Frigo P., Giuffrida C., Bos H., Razavi K. TRRespass: Exploiting the Many Sides of Target Row Refresh. USENIX Security 2020.

[2] van de Goor A. J., Tlili I. B. S. March tests for word-oriented memories. IEEE Transactions on Computers, vol. 47, no. 5, 1998.

[3] Intel 64 and IA-32 Architectures Software Developer’s Manual, Vol. 3B, Chapter 15 (Machine-Check Architecture).

[4] JEDEC Standard No. 21-C, Memory Module Annex K (DDR3 SPD), Annex L (DDR4 SPD).

ссылка на оригинал статьи https://habr.com/ru/articles/1039280/