【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吧
了解一下么 mark 一下 本帖最后由 reticencezcl 于 2018-3-10 12:12 编辑
终于好了 谢谢分享,我来试试 我已经按照教程屏蔽了独显,但是放进patched文件夹开机没起作用,能帮忙看看吗?
独显相关文件在ssdt5,包含ec访问,已转移到reg,
https://pan.baidu.com/s/1-q2nFmSge58tUCp64ZmLQA 文件包含屏蔽修改文件和无错dsl文件
qini95 发表于 2018-3-14 20:30 https://www.pcbeta.com/static/image/common/back.gif
我已经按照教程屏蔽了独显,但是放进patched文件夹开机没起作用,能帮忙看看吗?
独显相关文件在ssdt5,包 ...
你的SSDT-DGPU的hotpatch给出来,还有“没作用”是在-v模式下出现了什么错误? 感谢提醒,刚看了下改后没调用off,现在以屏蔽成功了。0.0
马虎的我
reticencezcl 发表于 2018-3-15 11:25
你的SSDT-DGPU的hotpatch给出来,还有“没作用”是在-v模式下出现了什么错误?
感谢提醒,马虎了。 qini95 发表于 2018-3-15 13:50 https://www.pcbeta.com/static/image/common/back.gif
感谢提醒,马虎了。
{:9_362:}不客气,祝你成功 mark一下,回去看,谢谢楼主 虽然看不懂,等我装好黑苹果后再研究 科普帖子 值得一顶 ,谢谢分享经验 一直在寻找 谢谢了 进来学习下 关于为何调用_PS3可以看15F 的解释 hotpatch好用不。 看的有点懵逼,再研究研究。 学习学习!