Как сделать DSDT с чистого листа

Страницы:  1

Ответить
Автор
Сообщение

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

Он существует для Мак и для Виндоус.
Еще вы должны запастись описанием языка АЦПИ 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, но в них нет особого интереса
Код:
iasl -d SSDT*.aml
Опция -da делает волшебную вешь, она ищет символы сразу по всем файлам, так что в итоге не должно оставаться неизвестных символов.
Мы декомпилируем тот DSDT, который нам пропатчил Кловер, и таким образом уже имеем массу полезных фиксов. Аналогично можно пропатчить оригинальный файл
$ iasl -da SSDT*.aml DSDT.aml
И иметь возможность сравнить, что было и что стало. А получился у нас файл с длинным именем DSDT-1234567.dsl, у вас будут другие цифры и буквы. Это исходная заготовка, которую нужно переименовать в DSDT.dsl, а оригинальный в DSDT-origin.dsl, редактировать и компилировать в бесконечном итерационном процессе:
1. Редактируем текстовым редактором.
2. Компилируем, получаем DSDT.aml
команда компиляции
Код:
$ iasl -ta DSDT.dsl
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
 
logo
Error