• Страница 1 из 1
  • 1
Как сделать DSDT с чистого листа
барбосДата: Среда, 15.03.2023, 23:56 | Сообщение # 1
Сержант
  • Группа:Администраторы
  • Сообщений:39
  • Регистрация:25.07.2011
  • 5
Задача.
Вот я купил новый компьютер, на нем нет системы, и я хочу поставить туда Хакинтош. Откуда мне взять 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.

Успехов в создании минимально правильного ДСДТ!
Прикрепления: 1560237.png (316.9 Kb)
  • Страница 1 из 1
  • 1
Поиск: