关于OpenCore引导双系统的一些总结和讨论
本帖最后由 zhtengw 于 2019-10-25 20:58 编辑最近OpenCore越发火热,越来越多人想要换用OC引导来得到更为原生的macOS体验。而使用OC引导,其对ACPI表的修改将会传递给操作系统,有些人就会发现OC引导的Windows会出现无法启动、容易崩溃、激活失效等等问题。其实,在配置OpenCore的时候,我们只要做好以下几个注意事项,这些问题都可以避免,在享受更原生macOS的同时,也能比较优雅地切换Windows系统。
1、谨慎使用ACPI Patch的改名
1) 不要改动_PRW _DSM和_OSI,前两个可能使硬件在Windows下工作不正常,而对_OSI的改动会使得Windows启动时蓝屏。另外,如KBD、GFX0等等,只要不是必须的,都尽量不去改名。
2) 在ACPI Patch中所有改动了DSDT表中原始名称的,都应有相应的SSDT-xxx.aml重新实现原有名字的设备或函数,具体的就是一下第二部分的内容了。
2、自定义SSDT中应灵活应用’If (_OSI= (“Darwin”))’判断语句,使得改变后的功能只对macOS生效
1) 改名后重新实现的设备或函数,都要在内容里添加系统判断,如果是macOS,则使用改过的内容;如果不是macOS,则调用改名后的方法。
举个例子,很多笔记本会通过修改_Qxx函数的内容来实现在macOS下的亮度调节热键。这里以改动_Q15为例,首先在config.plist中会有一项改名:
Comment Find Replace
Change _Q15 to XQ15
5f513135 58513135
同时会有一个SSDT-key.aml重新写了一个_Q15函数,用以实现调节亮度的功能:
Method (_Q15, 0, NotSerialized)// _Qxx: EC Query
{
Notify (\_SB.PCI0.LPCB.KBD, 0x0405)
}这就是说,原本的_Q15函数被改名为XQ15了,所有调用_Q15函数的都执行SSDT-key中定义的的新命令。
但此时通过OC引导重启到Windows的话,会发现这个热键失效了,因为Windows中原本要执行的命令现在是在XQ15函数中了。所以,我们修改SSDT-key.aml,判断系统为macOS时,才执行新的命令,否则调用XQ15,使得这个热键在macOS和Windows下都按我们预想的方式工作: Method (_Q15, 0, NotSerialized)// _Qxx: EC Query
{
If (_OSI ("Darwin"))
{
Notify (\_SB.PCI0.LPCB.KBD, 0x0405)
}
Else
{
\_SB.PCI0.LPCB.EC.XQ15 ()
}
}
2) SSDT中新添加的设备,应定义其_STA函数,用于判断它是否工作。
比如,很多笔记本会添加一个ALS0虚拟环境光传感器,用于保存屏幕亮度,SSDT-ALS0.aml:
Device (_SB.ALS0)
{
Name (_HID, "ACPI0008")// _HID: Hardware ID
Name (_CID, "smc-als")// _CID: Compatible ID
Name (_ALI, 0x012C)// _ALI: Ambient Light Illuminance
Name (_ALR, Package (0x01)// _ALR: Ambient Light Response
{
Package (0x02)
{
0x64,
0x012C
}
})
}此时重启到Windows,你会发现设备管理器中也多出了一个传感器设备。这东西本来不应该出现在Windows中的,所以我们给ALS0设备定义_STA函数:
Device (_SB.ALS0)
{
Name (_HID, "ACPI0008")// _HID: Hardware ID
Name (_CID, "smc-als")// _CID: Compatible ID
Name (_ALI, 0x012C)// _ALI: Ambient Light Illuminance
Name (_ALR, Package (0x01)// _ALR: Ambient Light Response
{
Package (0x02)
{
0x64,
0x012C
}
})
Method (_STA, 0, NotSerialized)// _STA: Status
{
If (_OSI ("Darwin"))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}这样,ACPI只会告诉macOS系统有这么一个设备,而其他操作系统中完全找不到它的存在。
3、在OpenCore配置使用主板的UUID作为SystemUUID,以免破坏Windows的激活环境。
一般主板的UUID可以在BIOS中查看,如果BIOS中看不到,我们可以通过传统方式启动Windows(不能是OC引导),在命令行中查看。
打开cmd,输入wmic命令并回车,会看到提示符变成了 wmic:root\cli>,再输入命令csproduct list full,得到内容如下:
C:\Users\Aten>wmic
wmic:root\cli>csproduct list full
Description=Computer System Product
IdentifyingNumber=Default string
Name=MS-7B23
SKUNumber=
UUID=00000000-0000-0000-0000-309C23AE5B3E
Vendor=Micro-Star International Co., Ltd.
Version=1.0将这个UUID填入config.plist中的 Platforminfo->Generic->SystemUUID 即可。以上Windows中的查看方式也可以在配置好OpenCore引导后作为验证。
4、如果Windows安装在另外一块硬盘,确保该硬盘的EFI分区是第一个分区。
有些电脑出厂时硬盘的第一个分区是恢复分区,或者用别的引导工具安装Windows后在该硬盘没有建立ESP分区,这会导致OpenCore找不到Windows系统。此时只要调整硬盘分区,新建或移动ESP到该硬盘的第一分区即可,推荐在winPE下用DiskGenius操作。
总结:
就我看来,只要做到以上几点,OpenCore引导的双系统就比较有舒服的体验了。但是这些东西可能对于已经配置好了clover,想要转用OpenCore的人比较有帮助,而那些从头开始配置OpenCore的同志们,直接参考小兵GitHub中的OC-little可能会省事一点,因为里面的SSDT都已经做好了系统判断。个人水平有限,肯定有疏漏和错误,望大家多讨论交流。
扩展内容:
1、关于_OSI函数
_OSI函数是用于询问操作系统名称的,因为硬件厂商可能会在ACPI表中规定一些功能只在某些操作系统实现,以回避bug之类,而同时,操作系统也可以伪造回答,以规避bug或实现更多功能。
2、关于_STA函数
_STA用于描述设备的状态。ACPI表中的每个设备,在初始化之前,都会先执行_STA函数,去检测这个设备的状态,如果设备存在才初始化。如果没有显式定义_STA函数,这个设备则被默认是存在且能正常工作的。描述设备的状态主要靠_STA的返回值,它的返回值有32位,但目前只有末5位有定义:
位数 31:5 4 3 2 1 0
定义 未使用 是否有电池 是否正常工作 是否在UI中显示 是否激活并解码资源 是否存在
对以上定义,“是”则置该位为1,“否”则置为0。如果一个设备,没有电池,可以正常工作并在系统中显示,那它的_STA返回值就是二进制的01111,换成16进制就是0x0F,如果一个设备不存在,那返回值就是00000,即16进制0x00。
知道了_OSI和_STA的意义,我们便可以理解上面的自定义的_STA函数了。ACPI首先询问操作系统,你是不是Darwin内核,系统回答是,那么ACPI就得到_STA为0x0F,开始正常初始化设备;如果系统回答不是,那么_STA返回0x00,ACPI就会忽略这个设备,之后系统中也看不到这个设备了。
Method (_STA, 0, NotSerialized)// _STA: Status
{
If (_OSI ("Darwin"))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
参考资料:
1、OpenCore Configuration.pdf
2、ACPI规范
3、精解OpenCore-黑果小兵
好贴!请教一下楼主 OpenCore引导 config.plist—–DeviceProperties—–Block 如何禁用MATS、DMAR、BGRT? 使用OpenCore引导卡在 MACH Reboot xtwz 发表于 2019-10-25 17:04 https://www.pcbeta.com/static/image/common/back.gif
好贴!请教一下楼主 OpenCore引导 config.plist—–DeviceProperties—–Block 如何禁用MATS、DMAR、 ...
你这应该是在ACPI-Block里写吧。可以试试这样:
All YES
Comment Drop MATS
Enabled YES
OemTableId <0000000000000000>
TableLength 0
TableSignature <4D415453>
All YES
CommentDrop DMAR
Enabled YES
OemTableId<0000000000000000>
TableLength 0
TableSignature <444D4152>
这里TableSignature是你要禁用的表名对应的16进制子串,可以用HackinTool转换。
我没用过ACPI table Drop,不清楚行不行。你可以试试。
厉害了,感谢分享
新的引导没用过 其实不是必须的都不要改名。 感谢,但是不想折腾了· zhtengw 发表于 2019-10-25 18:03 https://www.pcbeta.com/static/image/common/back.gif
你这应该是在ACPI-Block里写吧。可以试试这样:
不要在oc下drop这两张表,尽量有dart=0 写的不错,oc请不要用改名,用ssdt并做系统判断 优秀文章,感谢分享! xjn819 发表于 2019-10-25 20:19 https://www.pcbeta.com/static/image/common/back.gif
不要在oc下drop这两张表,尽量有dart=0
感谢,因为我不知道如何解决他的卡住问题,所以只好直接回答他如何禁用ACPI表了。 xjn819 发表于 2019-10-25 20:20 https://www.pcbeta.com/static/image/common/back.gif
写的不错,oc请不要用改名,用ssdt并做系统判断
是的,我有强调尽量不要改名。但有些情况不改名没办法。比如thinkpad的亮度热键,它只响应EC._Qxx事件,没有PS2 code和ADB code,就没法用PS2-ADB映射的方式来工作,只能通过改名重新定义的方式实现功能。 yusanxing 发表于 2019-10-25 20:07 https://www.pcbeta.com/static/image/common/back.gif
其实不是必须的都不要改名。
恩,我有写,现在标红了 进来学习一下 昨天专用OC也遇到这个问题了,第一时间看到兄弟的发帖就用次方法修复了,真的非常好,昨天不知什么情况这贴又在审核,今天终于解放了,赶紧复制保存,以备不时之需。 415793633 发表于 2019-10-26 10:30 https://www.pcbeta.com/static/image/common/back.gif
昨天专用OC也遇到这个问题了,第一时间看到兄弟的发帖就用次方法修复了,真的非常好,昨天不知什么情况这贴 ...
谢谢,能帮到你真是太好了。 zhtengw 发表于 2019-10-25 18:03 https://www.pcbeta.com/static/image/common/back.gif
你这应该是在ACPI-Block里写吧。可以试试这样:
非常感谢 楼主的回复……感谢感谢 xtwz 发表于 2019-10-26 11:49 https://www.pcbeta.com/static/image/common/back.gif
非常感谢 楼主的回复……感谢感谢
不好意思,昨天每次修改和回复都要被审核好久,没能跟你及时交流讨论。 zhtengw 发表于 2019-10-25 20:37
感谢,因为我不知道如何解决他的卡住问题,所以只好直接回答他如何禁用ACPI表了。
嗯,你也知道oc只用一张acpi表,你在config里drop表的话,用oc引导的win也会把这张表drop掉,所以win会出问题,所以使用dart=0更好,作用等同 _dsm怎么改才是比较很科学的,像我的XHCI原生已经有_DSM,想改下。