hhwzhd 发表于 2016-9-8 21:15

从10个例子学习如何屏蔽Optimus独显

本帖最后由 hhwzhd 于 2016-9-9 09:27 编辑

论坛已经有很多屏蔽独显的教程了,但是很多是有问题甚至是错误的,造成新手根据教程改DSDT/SSDT也无法成功屏蔽独显,甚至有很多有经验的景友帮别人修改时也被这些教程误导。目前rehabman大神的方法是成功率最高的方法,但是我在帮别人修改的时候发现这个方法有时候没有用,而有些景友用了看起来比较奇怪的方法成功屏蔽了独显。所以我想写篇教程普及一下正确的方法,也希望能发现一些新的特殊的方法。而为了使教程更加清晰易懂,同时帮助景友,所以想有需要的朋友上传自己的DSDT/SSDT,我帮大家改并且把其中有代表性的写成例子。

尽可能无错的DSDT/SSDT是屏蔽独显的前提,所以先讲如何提取和反编译DSDT/SSDT
提取:
1.(推荐)在Clover界面按F4,Clover就会把所有ACPI表提取到EFI/Clover/ACPI/origin文件夹。注意有以x结尾的SSDT(比如SSDT-3x.aml)是动态加载的,每次开机都不同,是不需要的,可以直接删除。
2. 在Windows下用AIDA64(2楼有资源)提取。上方菜单栏->工具->ACPI浏览器。Save DSDT可以保存DSDT,Save Table中可以找到所有SSDT
3. 在Linux下,打开终端输入命令sudo cp -R /sys/firmware/acpi/tables ~/Desktop就可以在桌面看到所有DSDT和SSDT了,注意dynamic文件夹下的SSDT是动态加载的,直接删掉
4. 不推荐在OS X下提取,一般都是被Clover或变色龙修改过的

反编译(需要mac os环境)
先安装MaciASL到/Applications(中文:/应用程序)文件夹,然后在桌面新建一个acpi文件夹,把所有提取的DSDT/SSDT放进去,打开终端输入命令/Applications/MaciASL.app/Contents/MacOS/iasl61 -da -dl ~/Desktop/acpi/*.aml如果是Windows下提取的,改为命令/Applications/MaciASL.app/Contents/MacOS/iasl61 -da -dl ~/Desktop/acpi/*.bin然后acpi文件夹就有反编译的dsl文件了

原理:
最简单方法,在_INI方法里调用_OFF方法(可能有不同名字如_PS3, GPOF, OPOF等)。但是某些_OFF方法的实现,会由于它包含了对EC(Embedded Controller)的依赖,而使得它不能在_INI方法里被调用。对于这样的情况,整个_OFF方法或者它的一部分代码,需要被移动到_REG方法里,以延迟执行(当_REG方法接收的参数Arg0==3 且 Arg1==1时,它会在_INI方法之后被执行)(详见ACPI规范)。对于一些情况,在_REG方法里调用_OFF的时机太迟了,从而导致要么屏蔽独显失败,要么系统五国。对于这样的情况,修改_OFF方法,移除它对于EC的依赖,将变得必要。之后,我们就可以在_INI里调用它(移除了对EC的依赖的_OFF)。同时,在_OFF里移除的代码,需要加到_REG里去。这样,虽然EC关联的代码在后(_INI后)执行(因为代码加到了_REG里,所以后执行),但却能达到更好的效果(来自daxuexinsheng大大的翻译https://bbs.pcbeta.com/viewthread-1598800-1-1.html)
以上是最常见的方法,不过我还见过其他奇怪的方法,比如在_INI先调用_DSM改变某个值再调用_PS3, 或者在_DSM方法里调用_PS3等等。这个帖子想看一下Rehabman的方法是否适用于所有情况,如果不是,是否有类似以上特殊的方法可以解决,以及是否存在不可能用DSDT/SSDT屏蔽独显的情况。
下面请大家上传自己的DSDT/SSDT来测试一下

hhwzhd 发表于 2016-9-8 21:16

本帖最后由 hhwzhd 于 2016-9-14 12:33 编辑

2楼:资源下载楼为了节约大家的P币,资源都放在百度云
https://pan.baidu.com/s/1dEGXai1

hhwzhd 发表于 2016-9-8 21:17

本帖最后由 hhwzhd 于 2016-9-11 13:15 编辑

先看第一个例子,DSDT/SSDT可以在二楼网盘下载。
先删除x.aml结尾的SSDT,然后用上面的命令反编译生成dsl文件。然后找_OFF函数在哪个文件grep -l _OFF *.dsl发现在SSDT-9.dsl文件,打开SSDT-9.dsl发现有三个_OFF方法,不过我们需要的是显卡的_OFF,一般在PEGP下面Scope (\_SB.PCI0.PEG0.PEGP)
{
    ......
    Method (_OFF, 0, Serialized)// _OFF: Power Off
    {
      P8XH (Zero, 0x76)
      If (LEqual (CTXT, Zero))
      {
            Store (VGAR, VGAB)
            Store (One, CTXT)
      }
      SGOF ()
    }
}我们需要移除_OFF对EC的依赖,可以看到_OFF本身没有出现包含EC的代码,但是仍然需要看_OFF所调用的方法有没有对EC的依赖。首先看P8XH,Command+F寻找没有发现P8XH的定义,所以在其他文件,在终端输入命令grep -l P8XH *.dsl发现P8XH在DSDT.dsl也出现过,打开DSDT发现P8XH的定义Method (P8XH, 2, Serialized)
{
    If (LEqual (Arg0, Zero))
    {
      Store (Or (And (P80D, 0xFFFFFF00), Arg1), P80D)
    }
    If (LEqual (Arg0, One))
    {
      Store (Or (And (P80D, 0xFFFF00FF), ShiftLeft (Arg1, 0x08)), P80D)
    }
    If (LEqual (Arg0, 0x02))
    {
      Store (Or (And (P80D, 0xFF00FFFF), ShiftLeft (Arg1, 0x10)), P80D)
    }
    If (LEqual (Arg0, 0x03))
    {
      Store (Or (And (P80D, 0x00FFFFFF), ShiftLeft (Arg1, 0x18)), P80D)
    }
    Store (P80D, P80H)
}可以发现没有对EC的依赖(LEqual相等,Or,And逻辑运算,Store赋值,ShiftLeft,ShiftRight位运算,这些方法是不用继续检查的)
回到_OFF方法,发现还调用了一个SGOF方法,在SSDT-8.dsl找到SGOF的定义Method (SGOF, 0, Serialized)
{
    Store (LCTL, ELCT)
    Store (SVID, HVID)
    Store (SDID, HDID)
    Store (EMLW, DMLW)
    SPP0 ()
    Store (One, LNKD)
    While (LNotEqual (LNKS, Zero))
    {
      Sleep (One)
    }
    Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
    Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)
    Sleep (0x012C)
    Return (Zero)
}发现它本身有对EC的依赖Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)然后继续看SGOF调用的SPPO(这里就不贴出来了),没有发现对EC的依赖,所以我们只要移除这两行就行了。
修改后的SGOFMethod (SGOF, 0, Serialized)
{
    Store (LCTL, ELCT)
    Store (SVID, HVID)
    Store (SDID, HDID)
    Store (EMLW, DMLW)
    SPP0 ()
    Store (One, LNKD)
    While (LNotEqual (LNKS, Zero))
    {
      Sleep (One)
    }
    Sleep (0x012C)
    Return (Zero)
}然后需要找到_INI方法,发现也在SSDT-8.dslMethod (_INI, 0, NotSerialized)// _INI: Initialize
{
    Store (Zero, \_SB.PCI0.PEG0.PEGP._ADR)
}加入调用_OFF的代码后Method (_INI, 0, NotSerialized)// _INI: Initialize
{
    Store (Zero, \_SB.PCI0.PEG0.PEGP._ADR)
    External (\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
    _OFF()
}因为_OFF和_INI不在同一个文件,所以需要加上External声明。
移除了_OFF对EC的依赖并且在_INI调用了_OFF后,需要在_REG方法执行移除的代码
在DSDT中发现有好几个_REG方法,不过我们需要的是Device EC下面的_REGScope (_SB.PCI0.LPCB)
{
    Device (EC)
    {
      // 省略若干行
      Method (_REG, 2, NotSerialized)// _REG: Region Availability
      {
            If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
            {
                If (And (OEMF, One))
                {
                  // 省略若干行
      }
    }
}在_REG加入从SGOF移除的代码Scope (_SB.PCI0.LPCB)
{
    Device (EC)
    {
      // 省略若干行
      Method (_REG, 2, NotSerialized)// _REG: Region Availability
      {
            If (LAnd(LEqual(Arg0,3), LEqual(Arg1,1))){
                // 把从SGOF移除的代码放在这个{}里面
                Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
                Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)
            }
            If (LAnd (LEqual (Arg0, 0x03), LEqual (Arg1, One)))
            {
                If (And (OEMF, One))
                {
                  // 省略若干行
      }
    }
}其中If (LAnd(LEqual(Arg0,3), LEqual(Arg1,1))){
    Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
    Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)
}是指第一个参数Arg0等于3,并且第二个参数Arg1等于1时(在_INI之后),执行{}里面的两行代码。
好了,我们已经完成了所有应该做的修改,然后要把修改过的DSDT.dsl和SSDT-8.dsl重新编译成aml文件



然后把编译好的DSDT.aml和SSDT-8.aml放进Clover的patched文件夹,并且把其他没有修改过的SSDT0.aml,SSDT1.aml,SSDT2.aml,SSDT6.aml,SSDT7.aml,SSDT9.aml也放进patched文件夹,config.plist配置DropOEM=true,重启进入系统后系统信息->显卡里面就没有独显的信息了。

这个例子是一个很典型的例子,有_INI和_OFF方法,_OFF方法包含对EC的依赖,所以写的比较详细。之后的例子就不会在包括类似如何找_INI,_OFF方法,如何编译dsl为aml的步骤了。

下面是把上述修改做成的补丁# DSDT.dsl
into method label _REG parent_hid PNP0C09 code_regex ([\s\S]*) replace_matched
begin
If (LAnd(LEqual(Arg0,3), LEqual(Arg1,1)))\n
{\n
    Store (Zero, \\_SB.PCI0.LPCB.EC.FDAT)\n
    Store (0xBF, \\_SB.PCI0.LPCB.EC.FCMD)\n
}\n
%1
end;

# SSDT-8.dsl
into method label _INI insert
begin
External (\_SB_.PCI0.PEG0.PEGP._OFF, MethodObj)\n
_OFF()\n
end;

into method label SGOF code_regex .*EC.* removeall_matched;这样如果以后要改DSDT/SSDT直接打个补丁就行了,不用每次都手动修改。

hhwzhd 发表于 2016-9-8 21:17


备用楼:例子2

hhwzhd 发表于 2016-9-8 21:18


备用楼:例子3

hhwzhd 发表于 2016-9-8 21:18


备用楼:例子4

hhwzhd 发表于 2016-9-8 21:18


备用楼:例子5

hhwzhd 发表于 2016-9-8 21:19


备用楼:例子6

hhwzhd 发表于 2016-9-8 21:19


备用楼:例子7

hhwzhd 发表于 2016-9-8 21:19


备用楼:例子8

hhwzhd 发表于 2016-9-8 21:20


备用楼:例子9

hhwzhd 发表于 2016-9-8 21:20


备用楼:例子10

hhwzhd 发表于 2016-9-8 21:20


备用楼的备用楼

Demo47 发表于 2016-9-8 21:28

我就路过看看,刚刚发了求助帖

魔道逆天地 发表于 2016-9-8 21:55

{:5_262:}还以为写好了,,我去

关云长羽 发表于 2016-9-8 22:20

支持楼主分享经验

loonyeo 发表于 2016-9-9 07:21

等楼主分享{:5_264:}

花篮的花儿香 发表于 2016-9-9 07:31

支持楼主分享经验

griefhy 发表于 2016-9-9 09:22

期待更新,我的是屏蔽了一段时间又自动出来了。

YJack007 发表于 2016-9-9 10:24

感觉不错,希望成功
页: [1] 2 3 4
查看完整版本: 从10个例子学习如何屏蔽Optimus独显