Загрузка установщика macOS на самосборном ПК останавливается на строке apfs_module_start или зависает с ошибкой, связанной с AppleACPIPlatform, — одна из самых частых причин этого отсутствует SSDT-EC.aml, таблица, эмулирующая встроенный контроллер (Embedded Controller). Без неё macOS пытается обратиться к реальному EC материнской платы, чьи методы несовместимы с драйверами Apple, и процесс загрузки прерывается.

В этой статье разберём, что представляет собой файл SSDT-EC.aml, почему он обязателен практически для любого десктопного хакинтоша, как сгенерировать его автоматически или написать вручную, и какие ошибки чаще всего допускают при подключении таблицы в OpenCore.

Что такое SSDT и зачем нужен фиктивный EC

SSDT (Secondary System Description Table) — это дополнительная ACPI-таблица, которая загружается поверх основной таблицы DSDT и позволяет добавлять, переименовывать или отключать устройства без перепрошивки BIOS. Файлы с расширением .aml — это скомпилированный байт-код на языке ASL (ACPI Source Language).

Встроенный контроллер (EC, Embedded Controller) на реальных компьютерах Apple управляет питанием, вентиляторами и клавиатурой. macOS при загрузке ищет устройство EC в ACPI-пространстве. Проблема в том, что EC десктопных материнских плат имеет методы, несовместимые с AppleACPIEC, и попытка системы с ним взаимодействовать вызывает kernel panic или зависание.

Решение — подсунуть системе фиктивное устройство EC без реальных методов, «заглушку», которое удовлетворяет проверку macOS, но не выполняет никаких действий с железом. Именно это и делает SSDT-EC.aml.

💡

SSDT-EC.aml не управляет железом — это пустышка, которая лишь сообщает macOS, что устройство EC существует, и отключает конфликтующий реальный контроллер.

Когда SSDT-EC обязателен, а когда не нужен

Необходимость таблицы зависит от платформы. На десктопных системах Intel и AMD фиктивный EC требуется практически всегда: macOS отказывается загружаться без него на большинстве чипсетов. На ноутбуках ситуация иная — там реальный EC нужен для работы батареи и клавиатуры, поэтому вместо отключения применяется SSDT-EC с корректными переименованиями (обычно в связке с SSDT-BAT и SSDT-Keyboard).

  • 🖥️ Десктоп Intel — SSDT-EC обязателен, реальный EC отключается.
  • 🔴 Десктоп AMD — аналогично, таблица входит в базовый набор.
  • 💻 Ноутбук — используется модифицированный вариант без отключения реального EC.
  • ⚙️ Старые версии macOS — требования могут отличаться, сверяйтесь с гайдом под свою версию системы.
⚠️ Внимание: не применяйте десктопный вариант SSDT-EC на ноутбуке. Отключение реального контроллера приведёт к потере индикации батареи, неработающей клавиатуре или проблемам со сном.

Автоматическая генерация через SSDTTime

Самый надёжный способ получить корректную таблицу — утилита SSDTTime, которая анализирует дамп DSDT вашей конкретной платы и генерирует SSDT под неё. Работает в Windows, Linux и macOS, требует установленного Python.

Порядок действий выглядит так:

☑️ Создание SSDT-EC через SSDTTime

Выполнено: 0 / 6

Утилита сама определит путь к устройству EC в вашей DSDT (например, \_SB.PCI0.LPCB.EC или \_SB.PC00.LPCB.EC0) и сформирует корректный код. Это важно: путь отличается у разных производителей плат, и универсальный файл из интернета может не совпасть с вашей топологией.

💡

Вместе с SSDT-EC сгенерируйте за один проход SSDT-PLUG (управление питанием CPU) и SSDT-USBX (питание USB-портов) — это стандартный минимальный набор для десктопного хакинтоша.

Ручное создание и компиляция SSDT-EC

Если автоматика недоступна, таблицу можно написать вручную в текстовом виде (.dsl) и скомпилировать компилятором iasl. Типовой шаблон для десктопа выглядит примерно так:

DefinitionBlock ("", "SSDT", 2, "ACDT", "SsdtEC", 0)

{

External (_SB_.PCI0.LPCB, DeviceObj)

Scope (\_SB.PCI0.LPCB)

{

Device (EC)

{

Name (_HID, "ACID0001")

Method (_STA, 0, NotSerialized)

{

If (_OSI ("Darwin"))

{

Return (0x0F)

}

Else

{

Return (Zero)

}

}

}

}

}

Ключевые моменты этого кода:

  • 🔑 _HID "ACID0001" — идентификатор, который распознаёт драйвер AppleACPIEC.
  • 🍏 Проверка _OSI ("Darwin") — устройство активно только в macOS, в Windows оно отключено и не конфликтует с реальным EC.
  • 📍 Путь Scope — должен совпадать с реальным путём LPC-моста в вашей DSDT.

Компиляция выполняется командой:

iasl -ve SSDT-EC.dsl

Флаг -ve подавляет часть предупреждений внешних ссылок. Если компилятор выдаёт ошибку по имени пути — проверьте в дампе DSDT, как именно называется мост LPC у вашей платы (LPCB, LPC0 и т.д.).

Зачем нужна проверка _OSI ("Darwin")

macOS при загрузке отвечает «истина» на запрос _OSI("Darwin"), а Windows — нет. Благодаря этому одна и та же таблица включает фиктивный EC только под macOS и остаётся прозрачной для Windows, где реальный EC продолжает работать штатно. Это стандартный приём двойной загрузки.

Подключение таблицы в OpenCore

Готовый файл помещается в папку EFI/OC/ACPI. Дальше его нужно зарегистрировать в config.plist в разделе ACPI → Add: добавьте запись с путём к файлу, включённым флагом Enabled и корректным Comment для удобства.

Два типовых упущения на этом этапе. Первое — забытый снапшот: если редактируете конфиг через ProperTree, используйте команду OC Snapshot, чтобы не прописывать запись вручную. Второе — конфликт с патчами переименования: для десктопного SSDT-EC обычно не нужны бинарные переименования EC в config.plist, а лишние патчи могут сломать загрузку Windows из-под OpenCore.

⚠️ Внимание: после любого изменения в разделе ACPI обязательно проверяйте config.plist валидатором (например, через ocvalidate из поставки OpenCore). Синтаксическая ошибка в конфиге — частая причина «внезапно переставшей грузиться» системы.

Сравнение вариантов SSDT-EC

ВариантПлатформаРеальный ECОсобенности
SSDT-EC (десктоп)Intel/AMD ПКОтключаетсяТолько заглушка с _STA
SSDT-EC (ноутбук)НоутбукиОстаётся активнымБез отключения, часто со связкой SSDT-BAT
SSDT-EC-USBXСтарые гайдыОтключаетсяОбъединённый вариант, сейчас чаще разделяют
Файл из чужого EFIЛюбаяЗависит от автораРиск несовпадения путей ACPI
📊 Как вы получили SSDT-EC для своей сборки?
Сгенерировал через SSDTTime
Написал и скомпилировал вручную
Взял готовый из чужого EFI
Ещё не разобрался, система не грузится

Диагностика типичных проблем

Проверить, подхватился ли фиктивный EC, можно в уже загруженной системе через IORegistryExplorer: в дереве IOService должно появиться устройство с идентификатором ACID0001, к которому привязан AppleACPIEC. Если устройства нет — таблица либо не загрузилась, либо путь в Scope не совпал с вашей DSDT.

Когда загрузка по-прежнему зависает, действуйте последовательно. Включите verbose-режим (-v в boot-args) и сфотографируйте последние строки перед остановкой. Убедитесь, что SSDT-EC стоит в списке Add раньше таблиц, которые могут ссылаться на EC. Проверьте, что в разделе ACPI → Patch не осталось устаревших переименований EC из старых гайдов — они конфликтуют с новой таблицей.

💡

Держите в папке ACPI только реально используемые таблицы. Лишние SSDT «про запас» увеличивают шанс конфликтов и затрудняют поиск причины нестабильности.

Часто задаваемые вопросы

Можно ли взять SSDT-EC.aml из чужой готовой EFI-сборки?

Рискованно. Путь к LPC-мосту и имена устройств зависят от производителя и чипсета платы. Если путь не совпадёт с вашей DSDT, таблица просто не сработает или вызовет ошибку. Надёжнее сгенерировать файл через SSDTTime под своё железо.

Нужен ли SSDT-EC для загрузки Windows через OpenCore?

Нет, и правильно собранная таблица ему не мешает: проверка _OSI ("Darwin") делает фиктивное устройство невидимым для Windows. Проблемы возникают только с таблицами без этой проверки или с лишними бинарными патчами в config.plist.

Чем SSDT-EC отличается от SSDT-EC-USBX?

SSDT-EC-USBX — объединённый вариант, который помимо фиктивного EC создаёт устройство USBX для корректной подачи питания на USB-порты. В актуальных гайдах эти функции чаще разделяют на два файла: SSDT-EC и SSDT-USBX, что упрощает отладку.

Система загрузилась и без SSDT-EC — значит, он не нужен?

Не обязательно. На части плат загрузка возможна, но без корректного EC могут всплывать проблемы со сном, питанием USB или стабильностью при обновлениях macOS. Рекомендуется всё же добавить таблицу — это стандартный элемент базовой настройки.

Как проверить, что компиляция iasl прошла успешно?

Компилятор выводит строку вида «Compilation successful» с нулём ошибок (предупреждения допустимы). Рядом с исходником появляется файл .aml. Если есть ошибки — чаще всего дело в неверном пути устройства или пропущенном блоке External.