更新于 

RTC综述

版权©️声明 : 本文章出自 Xjn´s Blog RTC综述


这篇文章试图教育用户解决RTC(CMOS)记忆体相关的错误导致无法开机,卡F1,无法关机,时钟停止,无法唤醒等问题。此文章为《使用OpenCore引导黑苹果》的补充内容,因原文中RTC相关内容较为散乱,而特意补充。


特别提醒:在使用以下方式修复rtc的过程之前,强烈建议先短接主板CMOS以及清除NVRAM后再进行操作!NVRAM和CMOS存储位置不同,请确定两件事都做了!!


RTC的问题表现

  • 华硕等主板开机卡F1
  • 开机卡在PCI Configuration代码处
  • 睡眠后唤醒奔溃,得到的错误报告为:Sleep Wake Failure in EFI
  • 无法关机
  • 电脑时钟不走,或者睡眠唤醒后时钟不走

RTC如何工作

RTC为l2c下的从设备,rtc为系统提供时间,电源,硬件信息等指示数据,l2c主动联系从设备rtc获取信息,反馈给系统。这些信息都被注册在rtc的各个内存位置上,这些内存地址对应的数据可通过OC-liilte或者搜索自己主板型号的intel datasheet获得。

举例:
系统设定一个自动关机的时间,比如22:20分,此信息通过系统trigger到rtc,l2c扫到rtc信息,则自动关机。


苹果系统下RTC的问题如何产生?

问题主要是因为Apple。

  • Apple公司使用自己定义的Apple RTC,而普通主板可能引用了最新的AWAC装置来代替传统RTC而导致无法开机。
  • Apple公司使用自己定义的Apple RTC,Apple RTC记录的内存范围可能不被我们普通的主板所支持,超出了我们普通主板0x70-0x78范围而导致了错误。

如何解决上述问题

对于《苹果系统下RTC的问题如何产生?》,第一个问题是这样的:一些具有AWAC的设备我们可能需要禁用AWAC来启用Legacy RTC。这里可通过OC-Little包中的禁用AWAC来实现。其中SSDT-AWAC.dsl更适用于主板DSDT代码特别多的主板,请根据情况二选一并转换成aml后使用。


对于第二个问题,它可能带来的影响包括时钟不走,关机不断电,开机卡f1,无法唤醒,唤醒崩溃等。这种问题就像我之前说的,是因为apple rtc写入到了普通主板rtc不支持的范围而导致的。

我之前在主文章有写到通过二进制补丁来解决开机卡F1,但这种方式其实是不妥当的,这是因为:

  • 这种补丁会因为系统版本的更新而失效
  • 并不能控制Efiboot来写入RTC
  • 卡F1的因素过多,而二进制补丁不可能具有通用性

因此,OC团队提供了三种方式来更好的解决RTC引起的各种问题。

  • 提供DisableRtcChecksum选项来忽略RTC地址中的0x58-0x59范围。但遗憾的是此quirk只适用于0x58-0x59地址损坏的rtc情况,并不具备通用性。
  • ACDT团队提供了RTCMemoryFixup.kext让用户可以自主选择所有你想屏蔽的地址。此kext需要用二分法来使用。
  • 将此kext放入OC/Kexts下面,并在config中加载它。
  • 一般来说,我们CMOS的总内存池是从00-FF(这个是16进制,换算成10进制就是从0-255),我们可以通过增加boot-args:rtcfx_exclude=00-FF来完全屏蔽cmos(当然这样写你完全失去了cmos记忆的功能了)
  • 我们需要通过二分法来定位你出错的cmos位置。把00-FF分成两部分,也就是00-7F以及80-FF。我们分别填一次rtcfx_exclude=00-7F以及rtcfx_exclude=80-FF,试试看问题有没有解决。比如说我使用的rtcfx_exclude=80-FF是解决了,那我们继续对80-FF进行拆分为:0x80-0xBF 和 0xC0-0xFF。以此类推,直到你拆分到最后的那一段位置为止。
  • ACDT团队提供了写入NVRAM的方式来屏蔽RTC地址。如图,RTC-blacklist中 8586878889 代表屏蔽85 86 87 89的RTC地址,如果屏蔽85以及86则填写8586。注16进制。
    rtc-blacklist.png

特殊情况

有两个非常特殊的情况:

  • 一些主板本身的DSDT就把RTC的地址写错了,我们需要更正。比如,华硕299的主板没有对rtc的0x72以及0x73进行映射,源dsdt中的资源分配如下代码。0x70只加到了0x72之前,从0x74位开始加到了0x78之前,也就是0x72以及0x73被忽略。因此需要官方的ssdt对rtc的资源进行重新分配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Device (RTC)
{
Name (_HID, EisaId ("PNP0B00") /* AT Real-Time Clock */) // _HID: Hardware ID
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
{
IO (Decode16,
0x0070, // Range Minimum
0x0070, // Range Maximum
0x01, // Alignment
0x02, // Length
)
IO (Decode16,
0x0074, // Range Minimum
0x0074, // Range Maximum
0x01, // Alignment
0x04, // Length
)
IRQNoFlags ()
{8}
})
  • Smbus是一种可能已经被淘汰的总线方式,此部件在很多新的机型中已经不再被需要。但经证实在过往的一些mac版本中需要激活它才能进入睡眠唤醒,这是一种很奇怪的现象,但是一般来说此补丁不该被需要。请注意原文中的0x57应该根据自己的主板来决定。比如我的x299主板应该搜索x299 intel datasheet,获得自己主板的datasheet后,得知自己Smbus串口的位置为0xc6,替换原文中的所有0x570xc6。此SSDT应只用于debug。
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
/*
* SMBus compatibility table.
*/
DefinitionBlock ("", "SSDT", 2, "ACDT", "MCHCSBUS", 0x00000000)
{
External (_SB_.PCI0, DeviceObj)
External (_SB_.PCI0.SBUS, DeviceObj)

Scope (_SB.PCI0)
{
Device (MCHC)
{
Name (_ADR, Zero) // _ADR: Address
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (_OSI ("Darwin"))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}
}

Device (_SB.PCI0.SBUS.BUS0)
{
Name (_CID, "smbus") // _CID: Compatible ID
Name (_ADR, Zero) // _ADR: Address
Device (DVL0)
{
Name (_ADR, 0x57) // _ADR: Address
Name (_CID, "diagsvault") // _CID: Compatible ID
Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method
{
If (!Arg2)
{
Return (Buffer (One)
{
0x57 // W
})
}

Return (Package (0x02)
{
"address",
0x57
})
}
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (_OSI ("Darwin"))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}

Method (DTGP, 5, NotSerialized)
{
If ((Arg0 == ToUUID ("a0b5b7c6-1318-441c-b0c9-fe695eaf949b")))
{
If ((Arg1 == One))
{
If ((Arg2 == Zero))
{
Arg4 = Buffer (One)
{
0x03 // .
}
Return (One)
}

If ((Arg2 == One))
{
Return (One)
}
}
}

Arg4 = Buffer (One)
{
0x00 // .
}
Return (Zero)
}
}

References