reticencezcl 发表于 2018-3-9 20:18

【Hotpatch】安装10.13时屏蔽独显的方法分享(EC相关_OFF方法)

本帖最后由 reticencezcl 于 2018-3-10 11:22 编辑

我的历程:其实从OS X Yosemite晚期开始混迹远景,现在一看都5-6年了,从开始的底层小白混到现在的正常小白,好辛酸 {:9_353:},之前EI Captain用了3年了,后来为了拷贝文件方便(在windows和OS X之间),就在win10上装了个HFS+,看到一个帖子说装了HFS+后直接读取Apple盘的内容会出现不可描述的错误,好嘛~立刻重启,然后再也进不去了。。。。{:9_368:} 我不知道现在还会不会出错,不过大家使用这个软件还是小心为上。那恰好这时已经发布了10.13.3了,那肯定装最新的咯,就动手呗~然后发现怎么都进不去安装界面。。。。。。
我的准备:发现变了好多东西,加载AppleALC要配合lilu.kext了,多了好多新的内核文件,具体可以看Rehabman大神的这两个帖子https://www.tonymacx86.com/threads/guide-using-clover-to-hotpatch-acpi.200137/#post-1308262,三楼是关于屏蔽独显的,以及https://www.tonymacx86.com/threads/guide-disabling-discrete-graphics-in-dual-gpu-laptops.163772/(我的例子都是笔记本的,没用过台式,但应该差不多吧)
例子_a:部分笔记本的_OFF方法中不含EC相关的,这样的方式基本是最简单的,只需直接在_INI中调用_OFF首先肯定是clover按F4提取,取其中的DSDT和SSDT,放到你喜欢的位置,比如桌面的origin文件夹里,然后反编译:cd desktop/origin
iasl -da -dl *.aml
然后快速找出含_OFF的dsl,在终端中输入grep -i _OFF *dsl

会得到结果:SSDT-6-GBTUACPI.dsl:                              _OFF ()
SSDT-6-GBTUACPI.dsl:   Method (_OFF, 0, Serialized)// _OFF: Power Off
SSDT-6-GBTUACPI.dsl:   Method (_OFF, 0, NotSerialized)// _OFF: Power Off
SSDT-6-GBTUACPI.dsl:   Method (_OFF, 0, NotSerialized)// _OFF: Power Off
SSDT-6-GBTUACPI.dsl:   Store ("NvP2-_Off ", Debug)
也就是说这个方法在SSST-6中,找到我们需要的的_OFF方法,如下:Method (_OFF, 0, Serialized)// _OFF: Power Off
{
      P8XH (Zero, 0x76)
      If (LEqual (CTXT, Zero))
      {
               Store (VGAR, VGAB)
                Store (One, CTXT)
      }
      SGOF ()
}
发现没有EC相关的,再搜索SGOF方法,在SSDT-5中,这个方法里也没有和EC相关的,所以SSDT_DGPU可以写成这样,只要_OFF的路径正确就可以成功,如下:
DefinitionBlock("", "SSDT", 2, "hack", "D-DGPU", 0)
{
    External(\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
         Device(RMD1)
         {
                Name(_HID, "RMD10000")
                Method(_INI, 0, NotSerialized)// _INI: Initialize
                {
                        If (CondRefOf(\_SB.PCI0.PEG0.PEGP._OFF))
                        {
                                 \_SB.PCI0.PEG0.PEGP._OFF()
                         }
               }
      }
}
或者直接更简单的写成,如下:
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
    External(_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
    Method(_SB.PCI0.PEG0.PEGP._INI) { _OFF() }
}
有些情况下,得用_PS3代替_OFF,两个都得试试才知道哪个好,写法如下:(这个是我在上述Rehabman的帖子里看到的)
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
    External(_SB.PCI0.PEG0.PEGP._PS3, MethodObj)
    Method(_SB.PCI0.PEG0.PEGP._INI) { _PS3() }
}
然后重命名_INI方法--->>XINI即可
整体思路:直接用_INI方法调用_OFF

例子_b:第二种情况就是在_OFF方法中会有EC相关的内容,这时,需要将EC相关内容放到_REG方法中,以延迟启动(有点忘记原因了,应该是会先加载_INI,而后加载_REG。。。)
在这个例子中(具体可以阅读前面提到的Rehabman的链接),所需要的_OFF方法在SSDT-8.dsl中,看下原始代码:
Method (_OFF, 0, Serialized)// _OFF: Power Off
{
      If (LEqual (CTXT, Zero))
      {
      \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)
      If (LNotEqual (GPRF, One))
      {
             Store (VGAR, VGAB)
      }

      Store (One, CTXT)
      }

      SGOF ()
}
这里可以看到_OFF方法中含有EC相关内容,即\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero),所以在这里我们需要将_OFF修改,使ec相关的内容无效,修改如下:
Method(_OFF, 0, Serialized)
{
      If (LEqual (CTXT, Zero))
      {
      /* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */   ///*...*/中的内容会无效,也可以删除这行
      If (LNotEqual (GPRF, One))
      {
             Store (VGAR, VGAB)
      }
            Store (One, CTXT)
      }
       SGOF ()
}
而且也需要调用原始的_INI方法,但不调用原始的_OFF方法(后面会重命名),而调用修改后的_OFF,如下
Method(_INI)
{
      XINI() // 调用原始的_INI, 而现在已经被命名为XINI
      _OFF() // 调用修改后的 _OFF
      Method(_OFF, 0, Serialized)
   {
      If (LEqual (CTXT, Zero))
      {
      /* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */   ///*...*/中的内容会无效,也可以删除这行
      If (LNotEqual (GPRF, One))
      {
             Store (VGAR, VGAB)
      }
             Store (One, CTXT)
      }
       SGOF ()
      }
}
而将之前无效化的(删除的)\_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero)放在_REG方法中调用,即:
Scope(_SB.PCI0.LPCB.EC0)
{
       Method(_REG, 2)
      {
            XREG(Arg0, Arg1) // 调用原始的_REG, 而现在被命名为 XREG
            If (3 == Arg0 && 1 == Arg1) // EC ready?
            {
                  \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) //从_OFF转移过来的
       }
}
所以整个SSDT-DGPU可以写成:
DefinitionBlock("", "SSDT", 2, "hack", "D-GPU", 0)
{
    External(_SB.PCI0.RP05.PEGP, DeviceObj)
    External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
    External(_SB.PCI0.RP05.PEGP.XOFF, MethodObj)
    External(_SB.PCI0.RP05.PEGP.XINI, MethodObj)
    External(_SB.PCI0.LPCB.EC0, DeviceObj)
    External(_SB.PCI0.LPCB.EC0.XREG, MethodObj)
    External(_SB.PCI0.LPCB.EC0.SPIN, MethodObj)
    External(_SB.PCI0.RP05.PEGP.CTXT, IntObj)
    External(_SB.PCI0.RP05.PEGP.GPRF, IntObj)
    External(_SB.PCI0.RP05.PEGP.VGAR, FieldUnitObj)
    External(_SB.PCI0.RP05.PEGP.VGAB, BuffObj)
    External(_SB.PCI0.RP05.PEGP.SGOF, MethodObj)

       Scope(_SB.PCI0.RP05.PEGP)
      {
            Method(_INI)
            {
             XINI() // 调用原始的_INI, 而现在已经被命名为XINI
            _OFF() // 调用修改后的_OFF
             }
             Method(_OFF, 0, Serialized)
             {
                      If (LEqual (CTXT, Zero))
                      {
                     /* \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) */
                      If (LNotEqual (GPRF, One))
                     {
                              Store (VGAR, VGAB)
                      }
                     Store (One, CTXT)
                      }
            SGOF ()
            }
      }
      Scope(_SB.PCI0.LPCB.EC0)
      {
            OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF)
            Method(_REG, 2)
            {
                   XREG(Arg0, Arg1) // 调用原始的_REG, 而现在被命名为 XREG
                  If (3 == Arg0 && 1 == Arg1) // EC ready?
                  {
                         \_SB.PCI0.LPCB.EC0.SPIN (0x96, Zero) //从_OFF转移过来的
                  }
            }
   }
}
其中OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF) ,添加这个是因为在编译时会出现“39, 3079, _REG has no corresponding Operation Region”的警告,添加这个可以解决。
然后我们需要重命名这几个方法:
_SB.PCI0.RP05.PEGP._INI -> XINI
_SB.PCI0.RP05.PEGP._OFF -> XOFF
_SB.PCI0.LPCB.EC0._REG -> XREG
需要用到这几个方法所在的*dsl文件,比如这里是DSDT.aml, SSDT-7.aml, and SSDT-8.aml,在终端中输入
iasl -dl -l DSDT.aml SSDT-7.aml SSDT-8.aml
可以得到三个*dsl,比如需要重命名_REG,它在dsdt中,打开,并搜索找到它的位置
Method (_REG, 2, NotSerialized)// _REG: Region Availability
            {

D2B8: 14 12 5F 52 45 47 02                           // .._REG.

                If (LEqual (Arg0, 0x03))
                {

D2BF: A0 0B 93 68 0A 03                              // ...h..

                  Store (Arg1, ECFL)
                }
            }
      }
    }
就可以写成
Comment:change Method(_REG,0,Serialized) to XREG, optionally pair with SSDT-DGPU.aml
Find:5F 52 45 47 02
Replace:58 52 45 47 02
Replace中的数值,应该是随便一个数字更改,这里将5F改成58,_INI与_OFF方法也类似,在相应的*dsl文件中找到其位置,再更改数值,这样就完成了整个屏蔽独显的hotpatch,最后放入clover中加载,sortorder中也加入相应SSDT的名字。
整体思路:移除_OFF中的EC相关内容,调用原始_INI方法下的修改后的_OFF方法,而EC部分转移到_REG方法中

例子_c:这是我自己的例子与例子b稍有不同,我的_OFF方法之中没有EC相关的内容,但是在_OFF方法中的SGOF方法中却有,我们看下原始代码
SSDT-6中的原始_OFF:
Method (_OFF, 0, Serialized)// _OFF: Power Off
{
       P8XH (Zero, 0x76)
      If (LEqual (CTXT, Zero))
      {
            Store (VGAR, VGAB)
            Store (One, CTXT)
      }

            SGOF ()
}
这里并没有与EC相关内容,于是我们查看下SGOF方法,找到在SSDT-5中:
Method (SGOF, 0, Serialized)
{
      If (LEqual (CCHK (Zero), Zero))
      {
            Return (Zero)
      }

      Store (Zero, ONOF)
      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)    //EC相关
      Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)//EC相关
      Sleep (0x012C)
      Return (Zero)
}
在SGOF中有与EC相关内容,于是采取如下策略:因_OFF不直接关联EC,所以在_INI方法中可调用原始的_OFF,但是_OFF得调用修改后的SGOF,可以写成如下:
Method (_INI)// _INI: Initialize
{
      XINI() // call original _INI, now renamed XINI。调用原始_INI,这里被命名为XINI
      _OFF() // call _OFF   调用原始的_OFF,_OFF没有修改
      SGOF() // call patched SGOF   调用修改后的SGOF
}
然后是修改后的SGOF方法,我直接删除了EC相关内容:
Method (SGOF, 0, Serialized)
{
      If (LEqual (CCHK (Zero), Zero))
      {
            Return (Zero)
      }

      Store (Zero, ONOF)
      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)
}
然后把EC部分移动到——REG方法中调用,如下:
Method (_REG, 2, NotSerialized)// _REG: Region Availability
{
            XREG(Arg0, Arg1) //调用原始_REG,被命名为XREG   
            If (LAnd(LEqual(Arg0,3),LEqual(Arg1,1)))
            {
                Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
                Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)
            }
}
所以SSDT-DGPU可以写成:
DefinitionBlock("", "SSDT", 2, "hack", "DGPU", 0)
{
    External(\_SB.PCI0.PEG0.PEGP, DeviceObj)
    External(\_SB.PCI0.PEG0.PEGP._OFF, MethodObj)
    External(_SB.PCI0.LPCB.EC.XREG, MethodObj)
    External(\_SB.PCI0.PEG0.PEGP.XINI, MethodObj)
    External (CCHK, MethodObj)
    External(ONOF, IntObj)
    External(LCTL,IntObj)
    External(ELCT, IntObj)
    External(SVID, IntObj)
    External(HVID, IntObj)
    External(SDID, IntObj)
    External(HDID, IntObj)
    External(EMLW, IntObj)
    External(DMLW, IntObj)
    External(LNKD, IntObj)
    External(LNKS, IntObj)
    External(SPP0, MethodObj)
    External(_SB_.PCI0.LPCB.EC__.FCMD, FieldUnitObj)
    External(_SB_.PCI0.LPCB.EC__.FDAT, FieldUnitObj)
    External(_SB.PCI0.LPCB.EC, DeviceObj)

    Scope (\_SB.PCI0.PEG0.PEGP)
    {
      Method (_INI)// _INI: Initialize
      {
            XINI() // call original _INI, now renamed XINI
            _OFF() // call _OFF
            SGOF() // call patched SGOF      
      }

      Method (SGOF, 0, Serialized)
      {
            If (LEqual (CCHK (Zero), Zero))
            {
                Return (Zero)
            }

            Store (Zero, ONOF)
            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)
         }
    }
    Scope (_SB.PCI0.LPCB.EC)
    {
      OperationRegion(RME3, EmbeddedControl, 0x00, 0xFF)
      Method (_REG, 2, NotSerialized)// _REG: Region Availability
      {
            XREG(Arg0, Arg1) // call original _REG, now renamed XREG
            //added to turn nvidia/radeon off
            If (LAnd(LEqual(Arg0,3),LEqual(Arg1,1)))
            {
                Store (Zero, \_SB.PCI0.LPCB.EC.FDAT)
                Store (0xBF, \_SB.PCI0.LPCB.EC.FCMD)
            }
      }      
    }
}
然后,这里需要重命名方法是_INI方法,SGOF方法和_REG方法,方法参见例子_b末尾,
_INI -> XINI
SGOF -> XGOF
_REG -> XREG
在Rehabmana的帖子中还有一个PGOF的例子,需要的景友具体可以开头提到的链接里看看
整体思路:对于_OFF方法,里面没有EC相关,直接放在_INI中调用,但是_OFF方法中的SGOF方法重新修改,即调用原始_OFF方法,但其中的SGOF方法则调用修改后的;然后把EC部分丢到_REG中。

这里是我的修改好的SSDT-DGPU和原始SSDT








这里感谢下 limurphy 大神的提点,让我解决了电池驱动问题,也感谢之前其他景友的帮忙

我保证不会再改了,只要不出问题,我也不想的。。。。天知道第一次编辑全挂了{:9_365:}
如果有错误,或者描述不准确请大家多多担待,大家新年快乐~
我要睡觉了。。。


这个代码编辑器这么坑爹吗,又丢的只剩下第一行,算了不用这个了,我最后再试一次,再上传个PDF吧,上面编辑出错的看PDF吧





loveqp 发表于 2018-3-9 21:35

了解一下么

lovemarsh 发表于 2018-3-9 21:45

mark 一下

reticencezcl 发表于 2018-3-9 22:05

本帖最后由 reticencezcl 于 2018-3-10 12:12 编辑

终于好了

chenlinyu 发表于 2018-3-11 10:02

谢谢分享,我来试试

qini95 发表于 2018-3-14 20:30

我已经按照教程屏蔽了独显,但是放进patched文件夹开机没起作用,能帮忙看看吗?

独显相关文件在ssdt5,包含ec访问,已转移到reg,

https://pan.baidu.com/s/1-q2nFmSge58tUCp64ZmLQA   文件包含屏蔽修改文件和无错dsl文件

reticencezcl 发表于 2018-3-15 11:25

qini95 发表于 2018-3-14 20:30 https://www.pcbeta.com/static/image/common/back.gif
我已经按照教程屏蔽了独显,但是放进patched文件夹开机没起作用,能帮忙看看吗?

独显相关文件在ssdt5,包 ...

你的SSDT-DGPU的hotpatch给出来,还有“没作用”是在-v模式下出现了什么错误?

qini95 发表于 2018-3-15 13:47

感谢提醒,刚看了下改后没调用off,现在以屏蔽成功了。0.0
马虎的我

qini95 发表于 2018-3-15 13:50

reticencezcl 发表于 2018-3-15 11:25
你的SSDT-DGPU的hotpatch给出来,还有“没作用”是在-v模式下出现了什么错误?

感谢提醒,马虎了。

reticencezcl 发表于 2018-3-15 13:58

qini95 发表于 2018-3-15 13:50 https://www.pcbeta.com/static/image/common/back.gif
感谢提醒,马虎了。

{:9_362:}不客气,祝你成功

eastlhu 发表于 2018-3-15 15:35

mark一下,回去看,谢谢楼主

feitianzhu8 发表于 2018-3-16 22:55

虽然看不懂,等我装好黑苹果后再研究

kidddjh 发表于 2018-3-17 08:34

科普帖子 值得一顶 ,谢谢分享经验

350360471 发表于 2018-3-19 17:12

一直在寻找 谢谢了

WLS.pkg 发表于 2018-3-19 17:19

xyx5891 发表于 2018-3-19 22:20

进来学习下

reticencezcl 发表于 2018-3-20 12:39

关于为何调用_PS3可以看15F 的解释

kind1501 发表于 2018-3-28 20:50

hotpatch好用不。

百赖小生 发表于 2018-3-30 12:56

看的有点懵逼,再研究研究。

269007368 发表于 2018-3-31 13:36

学习学习!
页: [1] 2 3
查看完整版本: 【Hotpatch】安装10.13时屏蔽独显的方法分享(EC相关_OFF方法)