Yello
|
Как сделать DSDT с чистого листа Задача.
Вот я купил новый компьютер, на нем нет системы, и я хочу поставить туда Хакинтош. Откуда мне взять DSDT? Ну в большинстве случаев поставили несколько галочек в Кловере, и установка пошла!
Или вариант, взятьв интернете чей-то ДСДТ для такого-же компьютера, и тоже успешно.
Я хочу рассказать, как сделать все-таки свой вариант, и потом его улучшать. С момента покупки Dell Latiude E6430 прошло два месяца, и я все еще совершенствую свой ДСДТ, пока не надоест. Для чего мы редактируем DSDT?
Прежде, чем всем этим заниматься, ответьте для себя на вопрос, а чего вы хотите добиться? У вас что-то неправильно работает?
1. Отображение состояния батарейки (только ноутбуки)
2. Яркость экрана (только ноутбуки)
3. Сон и пробуждение
4. Адекватная реакция на включение в розетку (только ноутбуки). Пререквизиты.
Нужно иметь какой-то компьютер с какой-то операционной системой, чтобы можно было заниматься редактированием текстовых файлов.
Или вы уже на этот компьютер поставили macOS как-то, и теперь желаете усовершенствовать DSDT. Для любой операционной системы есть компилятор командной строки iasl. В том числе для Виндоус, iasl.exe запускается в командной строке как и в маке, имеет те же функции, и дает те же результаты. Редактировать тексты в Виндах неудобно, notepad не имеет подсветки синтаксиса и нумерации строк. Может кто знает более продвинутый редактор. В Маке полно вариантов, и Xcode, и BBEdit, и другие.
Для виндоуса на сайте acpica.org Windows Binary Tools Есть очень удобный редактор Open source cross-platform dsdt&ssdt analysis editor
![](https://i.applelife.ru/2020/11/479829_Snimok_ehkrana_2020-11-06_v_10.48.29.png)
Он существует для Мак и для Виндоус. Еще вы должны запастись описанием языка АЦПИ ACPI_6_2.pdf. Лучше брать новую версию, поскольку разбираться нужно с тем ДСДТ, что вам подсунул свежий БИОС. Создание заготовки Сначала сделайте себе флешку с Кловером, загрузочную, пусть даже без системы. Важно, чтобы она была в формате FAT32. Грузимся на этом компьютере с этой флешки до интерфейса Кловера. Жмем клавишу "O" (латинская буква Оу) или выбираем в меню значок Options. Заходим в раздел ACPI-> там находим DSDT Name: и вписываем BIOS.aml. Это точно тот DSDT, который вы смогли бы получить в виндах через Аиду. Спускаемся по меню и выбираем DSDT fixes -> там можно ставить галочки, клавой или мышкой. Ставим почти все галочки, которые не вызывают у Вас отторжения. К примеру не нужны Firewire, Airport, IDE если вы знаете, что у вас таких устройств нет. Все незнакомое лучше поставить. Возвращаетесь из этого подменю, и нажимаете последовательно клавиши F2, F4, F5. Можете выключать испытуемого, и нести флешку на тот компьютер, на котором будете редактировать файлы. Интересующие нас файлы находятся на флешке в папках EFI\CLOVER\ACPI\origin
EFI\CLOVER\misc Копируем эти папки в свою рабочую папку на компьютере, где есть iasl. Хоть с Маком, хоть с Виндой. Инструкции одинаковые, за исключением тонкостей типа наклона слеша. Декомпиляция Полученный DSDT.aml есть бинарный файл, его текстовым редактором не посмотришь.
Запускаем командную строку: cmd.exe в винде, Terminal.app в маке, что там в Линуксе не в курсе, вроде bash называется.
Код:
> cd РабочаяПапка\origin
то есть переход в ту самую копию папки, которую сняли с флешки. Положите в эту же папку iasl.exe, если вы в виндах, или установите iasl в систему, если вы в маке
Код:
$ sudo cp ~/Downloads/iasl /usr/local/bin/
Теперь, наконец, можно декомпилировать, то есть получить DSDT на читабельном языке. $ iasl -da SSDT*.aml DSDT-*.aml
В новых версиях iasl это не работает, поэтому делаем как нас просят
Код:
iasl -e SSDT*.aml -d DSDT.aml
Отдельно можно декомпилировать все SSDT, но в них нет особого интереса
Опция -da делает волшебную вешь, она ищет символы сразу по всем файлам, так что в итоге не должно оставаться неизвестных символов. Мы декомпилируем тот DSDT, который нам пропатчил Кловер, и таким образом уже имеем массу полезных фиксов. Аналогично можно пропатчить оригинальный файл $ iasl -da SSDT*.aml DSDT.aml И иметь возможность сравнить, что было и что стало. А получился у нас файл с длинным именем DSDT-1234567.dsl, у вас будут другие цифры и буквы. Это исходная заготовка, которую нужно переименовать в DSDT.dsl, а оригинальный в DSDT-origin.dsl, редактировать и компилировать в бесконечном итерационном процессе:
1. Редактируем текстовым редактором.
2. Компилируем, получаем DSDT.aml
команда компиляции
3. Тестируем, то есть кладем в папку EFI\CLOVER\ACPI\patched и запускаем систему.
4. Возвращаемся к пункту 1. К сожалению декомпиляция может завершиться со следующей ошибкой
Код:
Input file SSDT-10x.aml, Length 0x37F (895) bytes
ACPI: SSDT 0x0000000000000000 00037F (v02 PmRef Cpu0Cst 00003001 INTL 20120913)
Pass 1 parse of [SSDT]
ACPI Error: [C3ST] Namespace lookup failure, AE_ALREADY_EXISTS (20160729/dswload-462)
ACPI Exception: AE_ALREADY_EXISTS, During name lookup/catalog (20160729/psobject-310)
Could not parse external ACPI tables, AE_ALREADY_EXISTS
Это означает что описание символа C3ST встретилось в двух разных SSDT, последняя из них это SSDT-10x.
В моем случае она оказалась сходной с SSDT-5x, отличаясь тем, что 5х это ACPI1.0, а 10x это ACPI2.0. А имена одинаковые! То-то у меня в кернел-логе сыплет, что-то навроде этого. Это ошибка БИОСа!
Так же в ноутбуке две одинаковые таблицы. Я проследил, они действительно обе присутствуют в БИОСе, это не моя ошибка.
Что делать? Перед компиляцией удалить дублера, а в реальной работе сделать в конфиге Кловера дроп лишних таблиц. В случае дублей улетят обе. Что исправлять 1. Ошибки синтаксиса, допущенные производителем данного компьютера
2. Смысловые ошибки
3. Трюки, найденные в интернете. Насчет этого пункта, все думают, что это единственное, что нужно сделать. Нет, первые два пункта тоже важны.
Вот, к примеру, патчи, собранные Рехабом. Пользоваться, или нет?
Я бы сказал "если только с умом". Ошибки синтаксиса Cмотрим сам файл DSDT.dsl и в самом файле видим первые проблемы
Код:
External (_SB_.PCI0.PEG0.VID_.LCD_, UnknownObj)
Это означает, что где-то в тексте есть ссылка на объект, а самого объекта нигде нет. Ищем. Он есть в SSDT-7. Получается, что он оттуда не экспортировался. Именно по этой причине к этому ноутбуку предлагают эту SSDT включать внутрь общей DSDT. Простым копированием текста, из той SSDT от первой фигурной скобки до последней в хвост DSDT.dsl перед последней скобкой. Вторая ошибка с отсутствующими символами
Код:
External (HNOT, MethodObj) // Warning: Unknown method, guessing 1 arguments
Поиск показывает, что метод упоминается в такой конструкции
Код:
If (CondRefOf (HNOT))
{
HNOT (Arg0)
}
Else
{
Notify (GFX0, 0x80) // Status Change
}
Тогда все в порядке, если метод неопределен, то и не выполняется. Мне непонятно, а как тогда компилируется? Лучше удалить это, оставить только Notify... Запускаю компиляцию только что полученного файла (я переименовал DSDT-1F2C3B4D.dsl в более простое DSDT1.dsl, как первая попытка)
Код:
$ iasl -ta DSDT1.dsl
1 errors, 14 warmings, 91 remarks, 109 optimisations
Ошибку надо исправлять, иначе нет результата.
Варнинги тоже надо исправлять, вдумываясь, почему компилятор ругается.
Это еще хорошая ситуация, я встречал и сотни ошибок при первой компиляции. В данном случае ошибка некритичная, в строке
Код:
Name (_HID, "*pnp0c14")
формат строки символов недопустимый, исправляется по науке так:
Код:
Name (_HID, EisaId ("PNP0C14") /* Windows Management Instrumentation Device */)
Исправлять нужно, иначе не скомпилируем, но на работу это не влияет, это виндусовая примочка. Варнинги реально более критичны, вот образцы исправлений.
- что было
+ что сделал
Код:
- CreateDWordField (BUF0, \_SB.PCI0._Y0F._LEN, MSLN) // _LEN: Length
+ CreateQWordField (BUF0, \_SB.PCI0._Y0F._LEN, MSLN) // _LEN: Length
Подсказка была в логе компиляции
Код:
ResourceTag larger then field (size mismatch tag 64bit, Field 32 bit)
Правило простое, tag - то, что нужно, field - что нужно исправить
tag=1 => CreateBitField
tag=8 => CreateByteField
tag=16 => CreateWordField
tag=32 => CreateDWordField
tag=64 => CreateQWordField Исправлять нужно, чтобы в реальной работе посылаемое значение не заехало на соседнее поле. Такой глюк никак не отловишь. Такой варнинг
Код:
Not all control path return a value
Ошибка логики, метод должен что-то возвращать, а получается, что в каких-то случаях ничего не вернет. И? Мак, конечно, не упадет, но и адекватности не ждите.
А что же там написать? Return(Zero) или Return(Local0)?
Чтобы успокоился компилятор, это сойдет, а вообще нужно смотреть логику. Аналогичный глюк
Reserved method should not return a value
Код такой
Код:
Method (_SRS, 1, Serialized) // _SRS: Set Resource Settings
{
Return (BUF2) /* \_SB_.PCI0.A_CC.BUF2 */
}
Открываем ПДФ, упомянутый выше, спецификация АЦПИ, находим поиском метод _SRS, и читаем, что он должен делать. Возврат значений там не предусмотрен. Поэтому переделываем следующим образом
Код:
Method (_SRS, 1, Serialized) // _SRS: Set Resource Settings
{
BUF2 = Arg0
}
Так вроде логичнее. Ну и всем известный варнинг
Код:
Name (_T_0, Zero)
Use of compiler reserved name _T_0
Чтобы этот варнинг не мозолил глаза, мы делаем сквозное переименование _T_0 на T_0.
!!! Нет смысла делать это переименование на уровне Кловера !!! Этих имен в исходном файле нет, их генерирует iasl при попытке компилировать конструкцию типа switch-case, не определенной стандартом.
После нашей перекомпиляции наш ДСДТ будет содержать нормальные конструкции If-Then-Else, более понятные макОСу. Смысловые ошибки Извините, но тут надо быть хоть немного программистом, чтобы их отлавливать. Подсказок ждать неоткуда. В исходном DSDT видим
External (CFGD, IntObj)
И эту переменную находим в SSDT CpuPm. И тут пора вспомнить, что мы эту таблицу дроппаем, вместе с этой переменной!
Надо ее скопировать в DSDT. Как и другие, которые могут пригодиться.
Код:
+ Name (CFGD, 0x0066F6FF)
+ Name (PDC0, 0x80000000)
+ Name (PDC1, 0x80000000)
+ Name (PDC2, 0x80000000)
+ Name (PDC3, 0x80000000)
+ Name (PDC4, 0x80000000)
+ Name (PDC5, 0x80000000)
+ Name (PDC6, 0x80000000)
+ Name (PDC7, 0x80000000)
+ Name (SDTL, Zero)
Общая ошибка это ОЕМ методы _DSM.
Это не ошибка производителя, это то, что он писал под виндоус, а у нас хакинтош.
Пример
Код:
- Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
{
- Name (_T_0, Zero) // _T_x: Emitted by ASL Compiler
If (Arg0 == ToUUID ("a5fc708f-8775-4ba6-bd0c-ba90a1ec72f8"))
{
While (One)
{
{
Видите UUID? Это из виндусового реестра, в Маке такого нет., и ничего выполняться не будет.
Это было бы пол беды, но если для виндов нормально иметь _DSM и для устройства, и для его мостика, то в Маке это вызывает краш.
Убиваем все чужие _DSM! Простой вариант
Код:
- Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
+ Method (ZDSM, 4, Serialized)
Сам по себе метод сохранился, но никто к нему уже не обратится, и паники не будет. Вот такой любопытный кусок
Код:
OperationRegion (DXHC, SystemMemory, 0xFED1F418, 0x04)
XHCD, 1
} If ((OSYS < 0x07D6) && (OSYS > 0x03E8))
{
XHCD = One
Notify (XHC, Zero) // Bus Check
}
Приглядевшись к адресу, я понял, что это Function Disable Bit.
Смысл операции в том, что для систем ниже, чем Windows Vista запретить USB3.
По-моему этот кусок надо вообще вырезать. А вот это уже лажа писателей
Код:
If ((OSYS > 0x07D0) || (OSYS < 0x07D6))
Диапазоны складываются и перекрывают вообще любое значение
Скорее там должно быть
Код:
If ((OSYS > 0x07D0) && (OSYS < 0x07D6))
Тогда диапазоны пересекаются.
Но дальше нужно смотреть, а что там в If, и что в Else.
У меня получилось, что правильнее в Then, поэтому исходную конструкцию
Код:
If ((OSYS > 0x07D0) || (OSYS < 0x07D6))
{
Notify (PCI0, Arg1)
}
Else
{
Notify (GFX0, Arg1)
}
Я сократил до вообще одного оператора
Notify (PCI0, Arg1)
Дело в том, что этот If проверяет, является ли система WindowsXP, и делает то, что в Then,
для систем типа Windows7,8,10 делает Else.
В чем отличие? В новых системах работает Optimus.
В macOS нам нужна нотификация первого типа, на всю шину. И аналогично нужно смотреть в других местах DSDT. Успехов в создании минимально правильного ДСДТ! Автор slice с applelife.ru
|