Отключение Nvidia Optimus и AMD Switchable Graphics.

Отключение Nvidia Optimus, AMD Switchable Graphics.

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

К тому же, этот мануал рассказывает общую логику, так что это может даже пригодиться для отключения других устройств. Например, вторая дискретная карта, которая стоит, допустим, для CrossFire или SLI, но в маке эти фишки не поддерживаются. Опять же – в целях экономии отключаем вторую карту. В общем и целом, применения этой логики уместно почти во всех случаях с устройствами типа _SB, то есть «южных» устройств.

Здесь мы отключаем с помощью метода _INI.

Через метод _REG нет смысла освещать, т.к. он менее приспособлен к современным условиям, и часто его бывает недостаточно. Тем более, товарищ RehabMan и так достаточно понятно рассказал об отключении через _REG в комментарии к своему патчу в репо.

Итак, начнём.

Первым делом мы ищем нашу видеокарту в IOKit’е, с помощью IORegistryExplorer (или же в отчёте с DarwinDumper’а, не важно).

  • Ключевые слова для поиска:
  • Nvidia: «NVDA», «NV», «IONDRVFramebuffer».
  • AMD ATi Radeon: «AMD», «ATY», «Controller».

В нашем случае это Nvidia Optimus. Смотрим:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-16-%d0%b2-7-38-24

 

Нам нужно лишь узнать путь к устройству. Смотрим его снизу вверх, чередуя через одну строчку, а записываем справа налево. Также помним, что в ACPI нет имён длиннее 4 символов.

Логика следующая:

  • IONDRVFramebuffer это программная часть, она нам не нужна. Пропускаем.
  • PXSX@0 это аппаратная часть. Записываем первую часть, до знака @, то есть записываем «PXSX».
  • IOPP – программная. Пропускаем.
  • RP05@1C,4 – аппаратная. Записываем правее PXSX, то есть «RP05.PXSX»
  • AppleACPIPCI – программная. Пропускаем.
  • PCI0@0 – аппаратная. Пишем правее RP05, то есть «PCI0.RP05.PXSX»

Выше идти не нужно. Запоминаем этот путь, и переходим к работе с ACPI.

Проводим действия согласно этой инструкции: osxpc.ru/faq/acpi-manual.

Работаем с файлами DSL, чтобы избежать проблем, и не запутаться ещё больше.

Ищем таблицу с графикой. В нашем случае, это SSDT-9.dsl.

Дерево устройств будет примерно таким:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-16-%d0%b2-8-15-33

Учитываем, что в примере учитывается путь RP05.PXSX, и соотносим со своими именами. Главное – помнить про путь, а точнее про имена в этом пути. В общем, будьте внимательны на этот счёт. Названия бывают очень разные, такие как…

Порты:

  • GFX0;
  • POP0;
  • RP0х;
  • PEGP…

Устройства:

  • PXSX;
  • PEGх;
  • NVDA;
  • _ATY…

После чего нажимаем Cmd+F, и вводим в появившееся окно «_INI»:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-16-%d0%b2-8-21-38

Смотрим, чтобы этот метод был в «папке» с нашим путём, выведенным ранее. Для этого смотрим на дерево устройств слева. Следовательно, мы наблюдаем примерно такой код:

Scope (\_SB.PCI0.RP05.PXSX)
{
//…Здесь может быть другой код, который описывает устройство…
Method (_INI, 0, NotSerialized// _INI: Initialize
{
Store (Zero, \_SB.PCI0.RP05.PXSX._ADR)
}
//…Здесь может быть другой код, который описывает устройство…
}

Собственно, наша задача – просто вызвать метод выключения, то есть _OFF.

Как это работает: компьютер обращается к устройству по адресу \_SB.PCI0.RP05.PXSX, что в переводе на человеческий выглядит так – «Южный мост, Шина PCI0, Порт 05, Физическое устройство». После этого он изучает описание, и после прочтения описания видит методы взаимодействия с ними. Самый первый метод – это метод _INI, который инициализирует (запускает) устройство, с помощью метода _ON. До правки этот метод содержит в себе только обращение по адресу \_SB.PCI0,RP05.PXSX._ADR, тем самым запуская запуская её физически, и цепляет в систему. Мы хотим добиться выключения. Для этого служит метод _OFF. Значит, нам нужно его исполнить. И чем раньше, тем лучше.

Но, мы должны узнать местоположение метода _OFF. Для этого опять же воспользуемся поиском (Cmd+F). Мы ищем метод «_OFF»:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-16-%d0%b2-8-51-40

В нашем случае, метод _OFF, который находится по пути \_SB.PCI0.RP05.PXSX, лежит в этой же таблице. Поэтому мы добавляем обращение к методу _OFF сразу же после обнаружения адреса устройства, чтобы _ON не успел сработать. Для этого просто добавляем его упоминание сразу после строки:

«Store (Zero, \_SB.PCI0.RP05.PXSX._ADR)».

Упоминание выглядит как «_OFF ()». Выглядит после правки это так:

Method (_INI, 0, NotSerialized// _INI: Initialize
{
Store (Zero, \_SB.PCI0.RP05.PXSX._ADR)
_OFF ()
  }

А если метод _OFF не был обнаружен в этой таблице, то мы со спокойной душой обозначаем то, что метод вынесен за пределы этого файла, просто прописав путь. Дальше iASL сам найдёт его. Запись внешнего метода выглядит так: External (\_SB.PCI0.RP05.PXSX._OFF, MethodObj)

Естественно, подставляем свой путь заместо указанного. Не забыли?:) Следовательно, код у нас выглядит так:

Method (_INI, 0, NotSerialized// _INI: Initialize
{
Store (Zero, \_SB.PCI0.RP05.PXSX._ADR)
External (\_SB.PCI0.RP05.PXSX._OFF, MethodObj)
_OFF ()
}

После этого мы просто сохраняем файлы как AML, поправив остальное (а-ля переименование GFX0 в IGPU и B0D3 в HDAU, и т.д.). Подкладываем эти таблицы клеверу в папку patched, чтобы он их загружал. Перезагружаем, и радуемся результату, проверив в IORegistry поиском по имени порта:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-16-%d0%b2-8-53-58

Если это не помогло, то нам нужно докинуть ещё одну табличку (которую многие знают как SSDT-1.aml), в которой более развернутый способ отключения. Глушит все вызовы, от того и является «универсальным». Вот он – SSDT-15.aml (15 чтобы уж точно не пересекалось с другими таблицами).

Всё, что нам нужно – поменять стандартные пути на наш. Для этого нажимаем Cmd+F, вводим стандартные пути в этом ссдт, которые перечислены в блоке External’ов, кроме IGPU,  ставим галочку Replace, и вписываем наше имя пути. Вот так:

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-11-17-%d0%b2-23-45-34

После этого подкидываем вместе с редактированной ранее таблицей клеверу, перезагружаемся, и радуемся отключённой графике.

Вот, собственно, и весь процесс отключения. Пример можете изучить в этом архиве. Ну и. конечно же. шпаргалка 🙂

Method (_INI, 0, NotSerialized// _INI: Initialize
{
Store (Zero, \_SB.PCI0.RP05.PXSX._ADR)
      // When method _OFF in OTHER SSDT: 
      //External (\_SB.PCI0.RP05.PXSX._OFF, MethodObj)
_OFF ()
}

Всегда Ваш, Андрей Чернышов.

P.S. – Спасибо Илье Исаеву за то, что объяснил алгоритм отключения 🙂

5 комментариев to “Отключение Nvidia Optimus и AMD Switchable Graphics.

  • Логика следующая:

    IONDRVFramebuffer это программная часть, она нам не нужна. Пропускаем.
    PXSX@0 это аппаратная часть. Записываем первую часть, до знака @, то есть записываем «PXSX».
    IOPP – программная. Пропускаем.
    RP05@1C,4 – аппаратная. Записываем правее <— Тут лучше левее. PXSX, то есть «RP05.PXSX»
    AppleACPIPCI – программная. Пропускаем.
    PCI0@0 – аппаратная. Пишем правее <— Тут лучше левее. RP05, то есть «PCI0.RP05.PXSX»

    Дабы не вгонять в заблуждение…=)

  • Всем привет! Кто поможет отключить Nvidia на ноутбуке Acer 5750g? Делаю все по инструкции, а графика не отключается. С чем это связано не знаю. Пробывал через _REG тоже не получается. Связаться со мной можно нажав на имя в этом посту и написать в ЛС.

  • Хорошо! Вот моя папка + мой рабочий config и IOReg: https://yadi.sk/d/7jSHXdpM38Wnpy

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.