进阶篇-电池热补丁
版权©️声明 : 本文章 神楽小白(GZ小白)的部落阁进阶:电池热补丁(Battery-Hotpatch)之路
前言
在有了OpenCore的引导后,已经不在推荐使用DSDT了,况且,现在也是主要推广热补丁(HotPatch),热补丁具有比DSDT更好的灵活性,于是便开始写这篇文章了。
准备步骤
首先,我们需要下载我提供的电池热补丁的样本(SSDT-BATT.dsl)。同时,我还准备了联想X260的电池热补丁作为例子。
链接如下:百度云 密码:fn1v
然后,准备你的DSDT或者SSDT(存储有EC缓冲区的,Embedded Controller Buffer)
需要工具:Hackintool,Maciasl,科学计算器(Mac自带)
要求:最好有一定的电池的基础知识,详细看见我之前写的电池DSDT的教程
初步动作
打开热补丁样本,我们来进行一些修改。(按照我自己的习惯来的)
我们要修改的有三处:
1.DefinitionBlock的修改,将这里的ACDT改为自己DSDT开头DefinitionBlock里的第三项
2.DefinitionBlock的修改,将最后的数值也改成自己DSDT里的
3.External引用路径里的EC路径,改成自己DSDT里的实际路径
这里我们有一处要修改:
1.Scope路径下,改为自己DSDT里的实际路径
16位和32位的处理
这里的处理,其实与DSDT里的差不多。
我们先将Field复制到SSDT里
像我这样复制下来,里面到内容不复制。
注意⚠️:你不难发现,我这里有许多的Field,那是因为X260的DSDT里,就是像这样的分散的Field。因此,当你制作电池热补丁时,搜索EmbeddedControllerBuffer找到Field后,记得同时搜索Field的名称,比如,ECOR,看看有没有分散在其它地方的
复制过来后,我们需要将Field进行改名,比如,ECOR,我改为了ECOX,这样就不会与原ACPI里的发生冲突。
热补丁与DSDT的拆分不同,我们直接将需要拆分的,拆好放到SSDT中,我们创建的Field下。
1 |
|
最后的结果就如上所示,正确拆分,正确计算偏移量。(这些都包含在我DSDT的教程中)
接着我们在DSDT中搜索需要被拆分的字节,找到所在的Method,记下路径,然后在SSDT里,添加这个路径。
比如我们,发现GBIF这个Method里面有需要拆分的自己,观察所得,GBIF所在的路径为:
那么我们就在SSDT中加上这个Scope:
1 |
|
然后,我们将GBIF这一整个Method复制到这个路径下,在对字节进行拆分。(以此类推,其它Method也是这么处理)
1 |
|
如上所示,即为最后的处理结果。
32位以上字节的处理
步骤基本相同,也是搜索所需修改字节对应对Method,然后找到对应路径,添加到SSDT中。
32位以上的,不需要Field下的更改,只需要改Method,进行RECB和WECB的处理
详细见DSDT教程中。
以下为完整处理结果(其实也在上文Method的GBIF,GBST中)(包含了全部)
1 |
|
可以对照给出的X260的热补丁看看
排错,补充引用声明
完成这些步骤后,点击编译会发现错误
这些都是因为没有被定义,因此我们需要进行引用,来排除这些错误。
以BATM为例,在DSDT中进行搜索,找到它被定义的路径和类型,写成External
1 | External (_SB.PCI0.LPC.EC_BATM, MutexObj) |
前者为路径,后者为类型
更多详见如下:
以下摘自iStar的博客:
Device:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
Method:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
Mutex:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
FieldUnit:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
Integer:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
Package:原始 ACPI 定义示例
1 |
|
补丁中添加的代码示例
1 |
|
添加if判断语句
为了让自己修改的Method不会影响Windows系统,我们需要添加if判断语句,明确它的内容作用在哪个系统。
如,在GBIF这个Method的第一个括号下加入If (_OSI (“Darwin”))
1 |
|
然后,我们去到这个Method的尾部,看看这个Method,最后有没有返回(Return)
很显然这个GBIF有的,就是Return (Arg1)
对于有返回语句的,我们需要在Else下加上Return,没有则不需要。
Else部分自己加在Method末尾。
最终结果如下:
1 |
|
我们发现,我将GBIF在Else中重命名为了XBIF,这需要与后面config里添加重命名对应。
那么,你们可能会有疑问,这个Arg0这些是这么来的?
这个需要观察:
1 |
|
就是中间这个数字得来的,3的话就是在XBIF后面的括号里填写,Arg0, Arg1, Arg2。
是多少,你就从Arg0开始往后一个个按顺序加。0就不填,留空。
添加完了这些后,你再编译,发现报错了,然后一样,补充引用声明。
如,
1 |
|
这样就可以了。
重命名与Mutex检查
最后,我们来进行重命名和Mutex检查
比如GBIF,我们来重命名为XBIF,这样就不会与ACPI中的GBIF冲突了
规则如下:
Comment:BAT GBIF to XBIF
利用Hackintool,将GBIF转换为16进制为:47424946
我们再补上两位,这两位就需要看Method了
1 |
|
NotSerialized代表0,Serialized代表8
我们将其相加,中间的数字+N或S
GBIF就是:3+0=3,3转换为16进制就是3
那么最后的两位就是03
XBIF的16进制为:58424946
完整的如下:
1 | Comment:BAT GBIF to XBIF |
GBST的就是:
1 | Method (GBST, 4, NotSerialized) |
1 | Comment:BAT GBST to XBST |
把这些重命名加到Config里。
你需要检查Mutex,确保他们全部为0 在当前使用的DSDT文件里搜索Mutex,看出现的几个变量是否为0,目前所知道的绝大多数机器的ACPI Mutex都是默认置0的,但是对于一些联想机器,它们往往有几个Mutex初始值并不是0,这里我们利用ACPI二进制更名的方法实现置0
以Mutex (BATM, 0x07)为例,先转换BATM为十六进制代码,得到42 41 54 4D
在前后加上完整定义的十六进制代码,01代表Mutex,07则代表默认值,最终得到 01 42 41 54 4D 07
我们的目的是使Mutex对象置0,所以config的更名应填
1 | Comment Set Mutex BATM, 0x07 to 0x0 |
其它Mutex对象按照同样的方法处理即可
这样下来你的电池热补丁就基本制作完毕了,对于双电池系统的电池(实际只有一块电池的),我们需要禁用其中一个。
双电池系统,屏蔽其中一个
比如,你的DSDT中有BAT0或BAT1两个电池设备,但你实际只在用其中一个。那么,你先看看另一个是否开启,如果另一个也是开启的,你需要屏蔽它。
参考我给的SSDT-BAT0-Disable-X260.aml
将DefinitionBlock框出来的位置,改成自己的,同时修改External和Scope为自己所要屏蔽的电池设备的路径。
然后保存即可。
然后我们要对所屏蔽电池设备下的_STA进行更名:
CLOVER:处理比较简单,将所需屏蔽的电池设备,转换为16进制,比如BAT1(42415430)
1 | Comment:BAT _STA to XSTA in BAT1 |
OC:OpenCore因为没有TgtBridge,因此处理比较麻烦
1.选择使用skip,count:Skip为跳过,就看你所要更改的_STA上有几个一样的_STA就跳过几个,count是替换次数,填1次即可
1 | Comment:BAT _STA to XSTA in BAT1 |
到这里,你已经做好一个电池热补丁和屏蔽补丁了,然后再加上ACPIBatteryManager.kext或者SMCBatteryManager.kext,不出问题,你就可以看到你可爱的电池图标了!
结语
加入博主的Hackintosh交流群:679838716