本帖最后由 p.H 于 2012-6-19 09:56 编辑
视频版链接:
自定义SSDT - 10.7.4电源管理优化 - 视频版
前言:10.7.4的升级,不像之前的升级那样不痛不痒
这次的升级由于升级了电源管理驱动(AppleIntelCPUPowerManagement.kext),引起了许多的问题
例如跑分得分减半,频率被锁,或者直接五国等诸多问题
之前针对这些问题,也有发过相关帖子,有兴趣的也可以参考一下:
10.7.4之后一些黑苹果的重要更新(持续更新)
10.7.4升级后的种种(5月14日更新OpenCL解法)
现在我们主要针对SSDT来进行一些讨论:
首先说说SSDT的基本概念,以下内容摘自ACPI规范:- 5.2.11.2 Secondary System Description Table (SSDT)
- Secondary System Description Tables (SSDT) are a continuation of the DSDT.
- The SSDT is comprised of a system description table header followed by data in Definition Block format.
- There can be multiple SSDTs present.
- After OSPM loads the DSDT to create the ACPI Namespace, each secondary system description table listed in the RSDT/XSDT with a unique OEM Table ID is loaded.
- Note: Additional tables can only add data; they cannot overwrite data from previous tables.
- This allows the OEM to provide the base support in one table and add smaller system options in other tables.
- For example, the OEM might put dynamic object definitions into a secondary table
- such that the firmware can construct the dynamic information at boot without needing to edit the static DSDT.
- A SSDT can only rely on the DSDT being loaded prior to it.
复制代码
拙译如下:
5.2.11.2 Secondary System Description Table (SSDT)
Secondary System Description Tables (SSDT)是DSDT的延续
SSDT是由系统描述表再加上定义块(Definition Block)格式的数据构成的
可以有若干个SSDT表同时存在
在OSPM加载了DSDT并为ACPI创建了命名空间后,
每个拥有唯一OEM ID且在RSDT/XSDT下的的SSDT会被加载
注意:额外的表只能够用来添加数据,他们不能够改写先前表中的数据
这使得OEM能够在一个表中提供基本支持,而在其他的表中添加更细微的系统选项
例如,OEM可能在第二个表中定义动态物件从而使固件能够在启动时建立动态信息而不需要更改静态的DSDT
SSDT必须建立在先加载的DSDT基础之上
现在我们基本上对SSDT有了一个初步的认识后
你可能会好奇,我的SSDT呢?我要如何获得我自己的SSDT?
下面的链接,将会你告诉你DSDT以及SSDT的提取步骤
黑苹果必读FAQ---初阶篇(5月14日更新)章节三
学习完了上面的基础知识后,我们可以正式开始我们的SSDT内容
首先是相关的工具及附件:
这次并不需要太多工具,基本上有DSDT Editor就够了
最新的DSDT Editor 0.8版:
DSDTEditor_Mac.zip
(1.13 MB, 下载次数: 2070)
一个查看P-states的kext:
MSRDumper.kext.zip
(13.83 KB, 下载次数: 2503)
以下内容适用Sandy Bridge用户
检测Sandy Bridge系列CPU SpeedStep(变频)最好的方法: 使用MSRDumper的内核拓展(kext)来读取含有当前P-State的MSR(Machine Specific Register)并且记录它
这个方法的一个缺点就是如果你长时间加载MSRDumper.kext的话 它会产生大量内核日志文件,当日志文件达到1000K时,它会自动保存并创建另外一个内核日志文件 最终这将占据相当大的一部分硬盘空间 因此,下面我将会叙述如何在终端中加载与停止加载它的方法
要做到第一件事便是更改MSRDumper.kext的权限 注:为了统一起见并减少出现各式各样的问题的可能性,均采用放置桌面来统一化代码,如果会终端,则不必拘泥于此 下载了附件之后,先双击解压,得到MSRDumper.kext,并把它移动到桌面,之后在终端中输入下列命令:
- cd desktop
- sudo chown -R 0:0 MSRDumper.kext
复制代码
当你想加载MSRDumper.kext的时候,输入下列命令: (请确保桌面有MSRDumper.kext)
- cd desktop
- sudo kextload MSRDumper.kext
复制代码
接着,在控制台里面单击内核日志你就能够看到如下显示内容:
- May 12 20:30:02 MacMans-MacBook-Pro kernel[0]: MSRDumper CoreMulti(31)
- May 12 20:30:02 MacMans-MacBook-Pro kernel[0]: MSRDumper PStatesReached: 8 11 15 19 23 25 26 27 28 29 30 31 33 34
- May 12 20:30:02 MacMans-MacBook-Pro kernel[0]: MSRDumper CoreMulti(31)
- May 12 20:30:02 MacMans-MacBook-Pro kernel[0]: MSRDumper PStatesReached: 8 11 15 19 23 25 26 27 28 29 30 31 33 34
-
- Note: These log entries are from my Early 2011 MacBook Pro.
复制代码
MSRDumper CoreMulti(31)显示了目前的P-state是31 MSRDumper PStatesReached: 8 11 15 19 23 25 26 27 28 29 30 31 33 34 则显示了自从加载MSRDumper.kext后,所有可见的P-states
第一次加载MSRDumper.kext的时候需要有点耐心 因为读取P-states需要一定的时间 而且你可能需要运行一些大型程序来改变当前P-states所处的状态
要停止MSRDumper继续运行产生大量信息,输入以下命令: (同样请确保桌面有MSRDumper.kext)
- cd desktop
- sudo kextunload MSRDumper.kext
复制代码
上述的MSRDumper.kext的问题搞定之后,我们再来看看SSDT
Credits to MacMan:http://macmanx86.blogspot.com/2012/05/customizing-ssdt-power-management.html
以下内容以SandyBridge平台的CPU为例,但不局限于SandyBridge,稍加变通即可
因为“关于本机”所使用的自动检测最大只能报告4.2GHz的CPU频率 所以我决定将MultiBeast内为超频用户提供的SSDT最大频率也限制在4.2GHz
在过去的几天里,有许多人都在询问如何通过自定义SSDT来在更高的CPU频率上运行 以及如何在未超频的系统上,看到更多的P-states 这篇教程目的在于解释SSDT内容以及自定义SSDT的方法
这里强调一点,如果你决定要使用SSDT的话,那么你需要对变色龙参数做如下设置: 打开chameleon wizard,确保你与下图红色方框中的内设置一致:
先让我们看看SSDT代码的第一个模块
- External (\_PR_.CPU7, DeviceObj)
- External (\_PR_.CPU6, DeviceObj)
- External (\_PR_.CPU5, DeviceObj)
- External (\_PR_.CPU4, DeviceObj)
- External (\_PR_.CPU3, DeviceObj)
- External (\_PR_.CPU2, DeviceObj)
- External (\_PR_.CPU1, DeviceObj)
- External (\_PR_.CPU0, DeviceObj)
复制代码
这个模块里面定义了实际或超线程可用CPU核心的个数 而在这个例子中,我们定义了8个CPU核心 如果你的CPU并没有那么多(例如酷睿i3或i5) 把从External (\_PR_.CPU4, DeviceObj)到External (\_PR_.CPU7, DeviceObj)的内容删除掉也是没问题的 但是如果你删除了的话,你需要在SSDT尾部删除其他与Scope (\_PR.CPU4) 到 Scope (\_PR.CPU7)相对应的条目 这是我的SSDT对应截图:
现在让我们进入下一部分:
- Scope (\_PR.CPU0)
- {
- Name (APSN, 0x04)
- Name (APSS, Package (0x1B)
- {
复制代码
这里我们在定义CPU0的详细信息 第一行是把0x4赋给APSN,这是一个Apple规范的物件(Apple-specific object) 下一个APSS同样也是一个Apple规范的物件 但是它与ACPI规范中的 _PSS 物件定义是一致的 这一行的关键在于Package (0x1B) 0x1B是一个16进制数,它标志着APSS内部含有的定义个数 而0x1B换算成十进制就是27 这意味着我们定义了27个状态(P-State)
接下来,让我们一起来看看添加了ACPI规范注释的 _PSS
- Package (0x06)
- {
- 0x1068, // CoreFreq
- Zero, // Power
- 0x0A, // TransitionLatency
- 0x0A, // BusMasterLatency
- 0x2A00, // Control
- 0x2A00 // Status
- },
复制代码
以下内容来源ACPI规范--8.4.4.2章节
所以在我们这个例子中,CoreFreq为0x0168,换算成十进制就是4200或者4.2GHz Apple似乎省略了Power的值 但你也可以使用主板提取的SSDT中Power的原始值 我发现Latency 和Bus Master Latency 的值一直是0x0A 下面是最后两个值,0x2A00也就是4200 现在我们不考虑后面的两个0并只考虑前面的两个数值 MSRDumper将能够显示这两个数对应的十进制数值 所以当系统运行在4.2GHz时,MSRDumper会显示P-State处在42
让我们继续分析下一个条目:
- Package (0x06)
- {
- 0x1004,
- Zero,
- 0x0A,
- 0x0A,
- 0x2900,
- 0x2900
- },
复制代码
这里0x1004换算成十进制就是4100或者4.1GHz 而后面的两个0x2900舍去两个0,0x29换算成十进制就是41,就这么简单 如果你继续对照下去,你会发现: 每变化一个状态,CoreFreq的值减少0x64(十进制100),Control和Status的值减少1 最后一项的CoreFreq应该是0x0640(换算成十进制就是1600),Control和Status是0x1000 这和Sandy Bridge桌面CPU最低频率为1600或者1.6GHz相符合
- Name (_PSS, Package (0x0D)
- {
- Package (0x06)
- {
- 0x09E5,
- 0x61A8,
- 0x0A,
- 0x0A,
- 0x13,
- 0x13
- },
- Package (0x06)
- {
- 0x095F,
- 0x5B5E,
- 0x0A,
- 0x0A,
- 0x12,
- 0x12
- },
- Package (0x06)
- {
- 0x08DA,
- 0x554B,
- 0x0A,
- 0x0A,
- 0x11,
- 0x11
- },
复制代码 以上是我的SSDT中的 _PSS 部分代码段
因为我的CPU不是Sandy Bridge系列,而是i3-380M
所以与上面的数据有一些出入,但是大体的问题仍然一样
0x09E5-0x095F=0x86=134(十进制) 符合我的CPU外频频率
0x13=19(十进制) 符合我的CPU最高倍频为19 到这里,你也可以对照一下自己的SSDT看看 像我有多个SSDT,所以打开每个SSDT来看一看,搜索一下对应的关键字便可
接下来让我们继续研究下一个Scope
- Scope (\_PR.CPU1)
- {
- Method (APSS, 0, NotSerialized)
- {
- Return (\_PR.CPU0.APSS)
- }
- }
复制代码
这里表示的是,我们将不把CPU0的信息在这里无谓的复制到别的CPU核心 而是通过让SSDT返回我们为CPU0所定义的信息的方法来达到CPU1与CPU0信息相同的结果 当然,你也可以为每一个核心定义各自的P-State,但这相当耗时 我所描述的这个方法简单多了而且工作量也小 这是我的SSDT中对应的截图: 不难发现,除了返回了CPU0的 _PSS,还返回了CPU0的 _PPC _PCT _PSD
最后我们可以来讨论自定义SSDT时,需要做哪些改变 如果你删除了某些P-State,你必须在Name (APSS, Package (0x1B) 的Package()里减少相应的值 MultiBeast中i7的SSDT最大频率为3.9GHz 这意味着,最上面的条目看起来应该像这样:
- Name (APSS, Package (0x18)
- {
- Package (0x06)
- {
- 0x0F3C,
- Zero,
- 0x0A,
- 0x0A,
- 0x2700,
- 0x2700
- },
复制代码
所以Package()里面的值由0x1B减去3得到0x18 并且第一个package中CoreFreq为0x0F3C(换算成十进制就是3900或3.9GHz) Control和Status则为0x2700(换算成十进制就是39)
类似的,如果你想增加state,记得每次向CoreFreq增加0x64, 向Control和Status增加1并确保Name (APSS, Package (0x18)中 Package()内的数值和你最终定义的P-States状态数相符合
其实最好的办法,就是如果你修改了Package里面定义的个数 那么你就把原来的Package(0x18)中括号的内容去掉,改为Package() 这样在编译的时候,机器会自动帮你计算,也省去了人为计算错误的麻烦
但是我们必须要知道,AppleIntelCPUPowerManagement能处理的状态数是有限的 如果你定义的P-States比你能使用的还多的话 例如在未超频的机器上使用为超频定制的SSDT 你将会失去P-States里面频率最低的那几个状态 当我在最高频率为3.8GHz的系统上使用MultiBeast为最高频率为4.2GHz超频定制的SSDT时 通过MSRDumper,你将能得到如下结果: MSRDumper PStatesReached: 16 23 24 25 26 27 38 而如果正常使用MultiBeast i7的SSDT时,则得到如下结果: MSRDumper PStatesReached: 16 17 18 19 20 21 35 36 37
你可能觉得不以为然?好吧,这和能耗有关 P-State(CPU频率)越低,能耗越低 所以从长远的角度来说,使用超频的SSDT将使你在能耗上面花费更多
希望大家都能够从这份教程中得到帮助
|