更新于 

进阶篇-电池热补丁

版权©️声明 : 本文章 神楽小白(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

OperationRegion (ECOX, EmbeddedControl, Zero, 0x0100)
Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
RCB0, 8,
RCB1, 8,
FCB0, 8,
FCB1, 8,
Offset (0xA8),
ACB0, 8,
ACB1, 8,
VOB0, 8,
VOB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
BMB0, 8,
BMB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
DCB0, 8,
DCB1, 8,
DVB0, 8,
DVB1, 8,
Offset (0xAA),
SNB0, 8,
SNB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
CHB0, 8,
CHB1, 8,
CHB2, 8,
CHB3, 8
}

最后的结果就如上所示,正确拆分,正确计算偏移量。(这些都包含在我DSDT的教程中)

接着我们在DSDT中搜索需要被拆分的字节,找到所在的Method,记下路径,然后在SSDT里,添加这个路径。
比如我们,发现GBIF这个Method里面有需要拆分的自己,观察所得,GBIF所在的路径为:

_SB.PCI0.LPC.EC

那么我们就在SSDT中加上这个Scope:

1
2
3
4

Scope (\_SB.PCI0.LPC.EC)
{
}

然后,我们将GBIF这一整个Method复制到这个路径下,在对字节进行拆分。(以此类推,其它Method也是这么处理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

Method (GBIF, 3, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (Arg2)
{
Or (Arg0, One, HIID)
Store (B1B2 (BMB0, BMB1), Local7)
ShiftRight (Local7, 0x0F, Local7)
XOr (Local7, One, Index (Arg1, Zero))
Store (Arg0, HIID)
If (Local7)
{
Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
}
Else
{
Store (B1B2 (FCB0, FCB1), Local1)
}

Store (Local1, Index (Arg1, 0x02))
Or (Arg0, 0x02, HIID)
If (Local7)
{
Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
}
Else
{
Store (B1B2 (DCB0, DCB1), Local0)
}

Store (Local0, Index (Arg1, One))
Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
If (Local7)
{
Store (0xC8, Index (Arg1, 0x06))
}
ElseIf (B1B2 (DVB0, DVB1))
{
Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
}
Else
{
Store (Zero, Index (Arg1, 0x06))
}

Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
Store (B1B2 (SNB0, SNB1), Local0)
Name (SERN, Buffer (0x06)
{
" "
})
Store (0x04, Local2)
While (Local0)
{
Divide (Local0, 0x0A, Local1, Local0)
Add (Local1, 0x30, Index (SERN, Local2))
Decrement (Local2)
}

Store (SERN, Index (Arg1, 0x0A))
Or (Arg0, 0x06, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
Or (Arg0, 0x04, HIID)
Name (BTYP, Buffer (0x05)
{
0x00, 0x00, 0x00, 0x00, 0x00
})
Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
Store (BTYP, Index (Arg1, 0x0B))
Or (Arg0, 0x05, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
}
Else
{
Store (0xFFFFFFFF, Index (Arg1, One))
Store (Zero, Index (Arg1, 0x05))
Store (Zero, Index (Arg1, 0x06))
Store (0xFFFFFFFF, Index (Arg1, 0x02))
}

Release (BATM)
Return (Arg1)
}
Else
{
Return (XBIF (Arg0, Arg1, Arg2))
}
}

Method (GBST, 4, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (And (Arg1, 0x20))
{
Store (0x02, Local0)
}
ElseIf (And (Arg1, 0x40))
{
Store (One, Local0)
}
Else
{
Store (Zero, Local0)
}

If (And (Arg1, 0x07)){}
Else
{
Or (Local0, 0x04, Local0)
}

If (LEqual (And (Arg1, 0x07), 0x07))
{
Store (0x04, Local0)
Store (Zero, Local1)
Store (Zero, Local2)
Store (Zero, Local3)
}
Else
{
Store (Arg0, HIID)
Store (B1B2 (VOB0, VOB1), Local3)
If (Arg2)
{
Multiply (B1B2 (RCB0, RCB1), 0x0A, Local2)
}
Else
{
Store (B1B2 (RCB0, RCB1), Local2)
}

Store (B1B2 (ACB0, ACB1), Local1)
If (LGreaterEqual (Local1, 0x8000))
{
If (And (Local0, One))
{
Subtract (0x00010000, Local1, Local1)
}
Else
{
Store (Zero, Local1)
}
}
ElseIf (LNot (And (Local0, 0x02)))
{
Store (Zero, Local1)
}

If (Arg2)
{
Multiply (Local3, Local1, Local1)
Divide (Local1, 0x03E8, Local7, Local1)
}
}

Store (Local0, Index (Arg3, Zero))
Store (Local1, Index (Arg3, One))
Store (Local2, Index (Arg3, 0x02))
Store (Local3, Index (Arg3, 0x03))
Release (BATM)
Return (Arg3)
}
Else
{
Return (XBST (Arg0, Arg1, Arg2, Arg3))
}
}

如上所示,即为最后的处理结果。

32位以上字节的处理

步骤基本相同,也是搜索所需修改字节对应对Method,然后找到对应路径,添加到SSDT中。
32位以上的,不需要Field下的更改,只需要改Method,进行RECB和WECB的处理

详细见DSDT教程中。

以下为完整处理结果(其实也在上文Method的GBIF,GBST中)(包含了全部)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245

Scope (\_SB.PCI0.LPC.EC)
{
Method (RE1B, 1, NotSerialized)
{
OperationRegion (ERM2, EmbeddedControl, Arg0, One)
Field (ERM2, ByteAcc, NoLock, Preserve)
{
BYTE, 8
}

Return (BYTE)
}

Method (RECB, 2, Serialized)
{
ShiftRight (Add (Arg1, 0x07), 0x03, Arg1)
Name (TEMP, Buffer (Arg1){})
Add (Arg1, Arg0, Arg1)
Store (Zero, Local0)
While (LLess (Arg0, Arg1))
{
Store (RE1B (Arg0), Index (TEMP, Local0))
Increment (Arg0)
Increment (Local0)
}

Return (TEMP)
}

OperationRegion (ECOX, EmbeddedControl, Zero, 0x0100)
Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
RCB0, 8,
RCB1, 8,
FCB0, 8,
FCB1, 8,
Offset (0xA8),
ACB0, 8,
ACB1, 8,
VOB0, 8,
VOB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
BMB0, 8,
BMB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
DCB0, 8,
DCB1, 8,
DVB0, 8,
DVB1, 8,
Offset (0xAA),
SNB0, 8,
SNB1, 8
}

Field (ECOX, ByteAcc, NoLock, Preserve)
{
Offset (0xA0),
CHB0, 8,
CHB1, 8,
CHB2, 8,
CHB3, 8
}

Method (GBIF, 3, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (Arg2)
{
Or (Arg0, One, HIID)
Store (B1B2 (BMB0, BMB1), Local7)
ShiftRight (Local7, 0x0F, Local7)
XOr (Local7, One, Index (Arg1, Zero))
Store (Arg0, HIID)
If (Local7)
{
Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
}
Else
{
Store (B1B2 (FCB0, FCB1), Local1)
}

Store (Local1, Index (Arg1, 0x02))
Or (Arg0, 0x02, HIID)
If (Local7)
{
Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
}
Else
{
Store (B1B2 (DCB0, DCB1), Local0)
}

Store (Local0, Index (Arg1, One))
Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
If (Local7)
{
Store (0xC8, Index (Arg1, 0x06))
}
ElseIf (B1B2 (DVB0, DVB1))
{
Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
}
Else
{
Store (Zero, Index (Arg1, 0x06))
}

Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
Store (B1B2 (SNB0, SNB1), Local0)
Name (SERN, Buffer (0x06)
{
" "
})
Store (0x04, Local2)
While (Local0)
{
Divide (Local0, 0x0A, Local1, Local0)
Add (Local1, 0x30, Index (SERN, Local2))
Decrement (Local2)
}

Store (SERN, Index (Arg1, 0x0A))
Or (Arg0, 0x06, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
Or (Arg0, 0x04, HIID)
Name (BTYP, Buffer (0x05)
{
0x00, 0x00, 0x00, 0x00, 0x00
})
Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
Store (BTYP, Index (Arg1, 0x0B))
Or (Arg0, 0x05, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
}
Else
{
Store (0xFFFFFFFF, Index (Arg1, One))
Store (Zero, Index (Arg1, 0x05))
Store (Zero, Index (Arg1, 0x06))
Store (0xFFFFFFFF, Index (Arg1, 0x02))
}

Release (BATM)
Return (Arg1)
}
Else
{
Return (XBIF (Arg0, Arg1, Arg2))
}
}

Method (GBST, 4, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (And (Arg1, 0x20))
{
Store (0x02, Local0)
}
ElseIf (And (Arg1, 0x40))
{
Store (One, Local0)
}
Else
{
Store (Zero, Local0)
}

If (And (Arg1, 0x07)){}
Else
{
Or (Local0, 0x04, Local0)
}

If (LEqual (And (Arg1, 0x07), 0x07))
{
Store (0x04, Local0)
Store (Zero, Local1)
Store (Zero, Local2)
Store (Zero, Local3)
}
Else
{
Store (Arg0, HIID)
Store (B1B2 (VOB0, VOB1), Local3)
If (Arg2)
{
Multiply (B1B2 (RCB0, RCB1), 0x0A, Local2)
}
Else
{
Store (B1B2 (RCB0, RCB1), Local2)
}

Store (B1B2 (ACB0, ACB1), Local1)
If (LGreaterEqual (Local1, 0x8000))
{
If (And (Local0, One))
{
Subtract (0x00010000, Local1, Local1)
}
Else
{
Store (Zero, Local1)
}
}
ElseIf (LNot (And (Local0, 0x02)))
{
Store (Zero, Local1)
}

If (Arg2)
{
Multiply (Local3, Local1, Local1)
Divide (Local1, 0x03E8, Local7, Local1)
}
}

Store (Local0, Index (Arg3, Zero))
Store (Local1, Index (Arg3, One))
Store (Local2, Index (Arg3, 0x02))
Store (Local3, Index (Arg3, 0x03))
Release (BATM)
Return (Arg3)
}
Else
{
Return (XBST (Arg0, Arg1, Arg2, Arg3))
}
}
}

可以对照给出的X260的热补丁看看

排错,补充引用声明

完成这些步骤后,点击编译会发现错误

这些都是因为没有被定义,因此我们需要进行引用,来排除这些错误。
以BATM为例,在DSDT中进行搜索,找到它被定义的路径和类型,写成External

1
External (_SB.PCI0.LPC.EC_BATM, MutexObj)

前者为路径,后者为类型

更多详见如下:

以下摘自iStar的博客:
Device:原始 ACPI 定义示例

1
2
3
4
5

Scope (_SB.PCI0.LPCB)
{
Device (H_EC)
{

补丁中添加的代码示例

1
2

External (_SB_.PCI0.LPCB.H_EC, DeviceObj)

Method:原始 ACPI 定义示例

1
2

Method (_STA, 0, NotSerialized) /* _STA: Status */

补丁中添加的代码示例

1
2

External (_SB_.BAT0._STA, MethodObj)

Mutex:原始 ACPI 定义示例

1
2

Mutex (BATM, 0x07)

补丁中添加的代码示例

1
2

External (_SB_.PCI0.LPCB.H_EC.BATM, MutexObj)

FieldUnit:原始 ACPI 定义示例

1
2
3
4
5
6
7

Field(...)
{
...
BCNT, 8,
...
}

补丁中添加的代码示例

1
2

External (_SB_.PCI0.LPCB.H_EC.BCNT, FieldUnitObj)

Integer:原始 ACPI 定义示例

1
2

Name (ECA2, Zero)

补丁中添加的代码示例

1
2

External (_SB_.PCI0.LPCB.H_EC.ECA2, IntObj)

Package:原始 ACPI 定义示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Name (PBIF, Package (0x0D)
{
One,
0xFFFFFFFF,
0xFFFFFFFF,
One,
0xFFFFFFFF,
0xFA,
0x96,
0x0A,
0x19,
"BAT0",
" ",
" ",
" "
})

补丁中添加的代码示例

1
2

External (_SB_.BAT0.PBIF, PkgObj)

添加if判断语句

为了让自己修改的Method不会影响Windows系统,我们需要添加if判断语句,明确它的内容作用在哪个系统。

如,在GBIF这个Method的第一个括号下加入If (_OSI (“Darwin”))

1
2
3
4
5
6
7
8

Method (GBIF, 3, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (Arg2)
.....

然后,我们去到这个Method的尾部,看看这个Method,最后有没有返回(Return)
很显然这个GBIF有的,就是Return (Arg1)
对于有返回语句的,我们需要在Else下加上Return,没有则不需要。

Else部分自己加在Method末尾。

最终结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

Method (GBIF, 3, NotSerialized)
{
If (_OSI ("Darwin"))
{
Acquire (BATM, 0xFFFF)
If (Arg2)
{
Or (Arg0, One, HIID)
Store (B1B2 (BMB0, BMB1), Local7)
ShiftRight (Local7, 0x0F, Local7)
XOr (Local7, One, Index (Arg1, Zero))
Store (Arg0, HIID)
If (Local7)
{
Multiply (B1B2 (FCB0, FCB1), 0x0A, Local1)
}
Else
{
Store (B1B2 (FCB0, FCB1), Local1)
}

Store (Local1, Index (Arg1, 0x02))
Or (Arg0, 0x02, HIID)
If (Local7)
{
Multiply (B1B2 (DCB0, DCB1), 0x0A, Local0)
}
Else
{
Store (B1B2 (DCB0, DCB1), Local0)
}

Store (Local0, Index (Arg1, One))
Divide (Local1, 0x14, Local2, Index (Arg1, 0x05))
If (Local7)
{
Store (0xC8, Index (Arg1, 0x06))
}
ElseIf (B1B2 (DVB0, DVB1))
{
Divide (0x00030D40, B1B2 (DVB0, DVB1), Local2, Index (Arg1, 0x06))
}
Else
{
Store (Zero, Index (Arg1, 0x06))
}

Store (B1B2 (DVB0, DVB1), Index (Arg1, 0x04))
Store (B1B2 (SNB0, SNB1), Local0)
Name (SERN, Buffer (0x06)
{
" "
})
Store (0x04, Local2)
While (Local0)
{
Divide (Local0, 0x0A, Local1, Local0)
Add (Local1, 0x30, Index (SERN, Local2))
Decrement (Local2)
}

Store (SERN, Index (Arg1, 0x0A))
Or (Arg0, 0x06, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x09))
Or (Arg0, 0x04, HIID)
Name (BTYP, Buffer (0x05)
{
0x00, 0x00, 0x00, 0x00, 0x00
})
Store (B1B4 (CHB0, CHB1, CHB2, CHB3), BTYP)
Store (BTYP, Index (Arg1, 0x0B))
Or (Arg0, 0x05, HIID)
Store (RECB (0xA0, 0x80), Index (Arg1, 0x0C))
}
Else
{
Store (0xFFFFFFFF, Index (Arg1, One))
Store (Zero, Index (Arg1, 0x05))
Store (Zero, Index (Arg1, 0x06))
Store (0xFFFFFFFF, Index (Arg1, 0x02))
}

Release (BATM)
Return (Arg1)
}
Else
{
Return (XBIF (Arg0, Arg1, Arg2))
}
}

我们发现,我将GBIF在Else中重命名为了XBIF,这需要与后面config里添加重命名对应。
那么,你们可能会有疑问,这个Arg0这些是这么来的?
这个需要观察:

1
2

Method (GBIF, 3, NotSerialized)

就是中间这个数字得来的,3的话就是在XBIF后面的括号里填写,Arg0, Arg1, Arg2。
是多少,你就从Arg0开始往后一个个按顺序加。0就不填,留空。

添加完了这些后,你再编译,发现报错了,然后一样,补充引用声明。
如,

1
2

External (_SB.PCI0.LPC.EC.XBIF, MethodObj)

这样就可以了。

重命名与Mutex检查

最后,我们来进行重命名和Mutex检查
比如GBIF,我们来重命名为XBIF,这样就不会与ACPI中的GBIF冲突了
规则如下:
Comment:BAT GBIF to XBIF
利用Hackintool,将GBIF转换为16进制为:47424946
我们再补上两位,这两位就需要看Method了

1
2

Method (GBIF, 3, NotSerialized)

NotSerialized代表0,Serialized代表8
我们将其相加,中间的数字+N或S
GBIF就是:3+0=3,3转换为16进制就是3
那么最后的两位就是03

XBIF的16进制为:58424946

完整的如下:

1
2
3
Comment:BAT GBIF to XBIF
Find:47424946 03
Replace:58424946 03

GBST的就是:

1
Method (GBST, 4, NotSerialized)
1
2
3
Comment:BAT GBST to XBST
Find:47425354 04
Replace:58425354 04

把这些重命名加到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
2
3
Comment Set Mutex BATM, 0x07 to 0x0
Find 01 42 41 54 4D 07
Repalce 01 42 41 54 4D 00

其它Mutex对象按照同样的方法处理即可

这样下来你的电池热补丁就基本制作完毕了,对于双电池系统的电池(实际只有一块电池的),我们需要禁用其中一个。

双电池系统,屏蔽其中一个

比如,你的DSDT中有BAT0或BAT1两个电池设备,但你实际只在用其中一个。那么,你先看看另一个是否开启,如果另一个也是开启的,你需要屏蔽它。

参考我给的SSDT-BAT0-Disable-X260.aml

将DefinitionBlock框出来的位置,改成自己的,同时修改External和Scope为自己所要屏蔽的电池设备的路径。

然后保存即可。

然后我们要对所屏蔽电池设备下的_STA进行更名:

CLOVER:处理比较简单,将所需屏蔽的电池设备,转换为16进制,比如BAT1(42415430)

1
2
3
4
Comment:BAT _STA to XSTA in BAT1
Find:5F535441
Replace:58535441
TgtBridge:42415431

OC:OpenCore因为没有TgtBridge,因此处理比较麻烦
1.选择使用skip,count:Skip为跳过,就看你所要更改的_STA上有几个一样的_STA就跳过几个,count是替换次数,填1次即可

1
2
3
4
5
Comment:BAT _STA to XSTA in BAT1
Find:5F535441
Replace:58535441
Skip:(填跳过的次数)
Count:1

到这里,你已经做好一个电池热补丁和屏蔽补丁了,然后再加上ACPIBatteryManager.kext或者SMCBatteryManager.kext,不出问题,你就可以看到你可爱的电池图标了!

结语

加入博主的Hackintosh交流群:679838716