- 积分
- 3424
- 最后登录
- 2016-1-20
- 精华
- 0
- 阅读权限
- 70
- 主题
- 111
- UID
- 984013
- 帖子
- 7884
- PB币
- 28167
- 威望
- 45
- 贡献
- 0
- 技术
- 2147
- 活跃
- 1597
打酱油归来
- UID
- 984013
- 帖子
- 7884
- PB币
- 28167
- 贡献
- 0
- 技术
- 2147
- 活跃
- 1597
|
发表于 2014-9-20 17:13:15
IP属地美国
|显示全部楼层
本帖最后由 lisai9093 于 2014-11-3 18:20 编辑
Reference: http://www.insanelymac.com/forum ... scussion/?p=1864061
http://www.projectosx.com/forum/index.php?s=&showtopic=3167&view=findpost&p=39912
http://www.projectosx.com/forum/index.php?s=&showtopic=3167&view=findpost&p=42019
http://www.projectosx.com/forum/index.php?showtopic=2428https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/pmset.1.html
感谢dmazar 大神辛苦工作,几乎独立开发了整个Aptio 驱动。
*小白慎入,此贴需要2进制/16进制基本计算。你的机器需要是纯UEFI 环境(模拟的应该不行,不过可以试试),并且不是所有机器都支持。
前言:
首先来看看这个AptioFix 是干什么用的。我们知道OS X 系统引导文件是boot.efi,引导过程中boot.efi 会加载内核kernel,所以需要从UEFI 固件中固定一部分内存区域放置kernel 保证它的运行。但是AMI Aptio 的固件无法像其它主板(比如Insyde EFI 和 Intel UEFI)自动释放kernel 所需的内存,所以在引导过程中出现了问题。为了解决这个问题,基本所有AMI UEFI 主板都需要AptioFix 这个补丁才能引导。但是dmazar 开发的初代AptioFix 补丁虽然解决了引导问题,但是牺牲掉了苹果电脑的一些功能。所以dmazar 开发了第二代AptioFix2 以解决第一代的不足。这也是这篇文章的目的,如何使用AptioFix2。
AptioFix2 的优点:
相比AptioFix 第一代(以下简称AptioFix),AptioFix2 支持内存碎片整理,Runtime 服务虚拟化,不依赖boot.efi 即能向kernel 添加boot-args,以及大部分人更关心的休眠功能。
原理:
前面介绍了AMI UEFI 主板无法正常腾出内存以加载kernel,所以引导出现问题。更详细点,boot.efi 会在地址值比较小的内存空间中加载kernel,也就是低地址内存(Low Address Memory)。但是一般主板的低地址基本已被占满。打个比方,就像大家停车都愿意在1层地面停车,所以地面车位最少,2层,3层停车位多。同理,低地址内存空余很少,所以AptioFix 从高地址找到空闲内存以加载kernel。但是这一步的关键是欺骗boot.efi,让其误以为空间需要重分配,达到转移内存的效果。也就是说AptioFix 必须基于boot.efi 重新分配内存功能才能发挥作用。这就是dmazar 不愿意看到的,如果一旦boot.efi 的代码更新了,AptioFix 与boot.efi 通信很可能就会发生错误(在Lion 时代出现过),不只是内存分配无法进行,就连最基本的boot-args 都无法从boot.efi 传到kernel。
AptioFix2 为了解决这个问题,与boot.efi 断绝关系。利用slide=xxx 参数手动选取可用内存以加载kernel 及其它服务比如Runtime Service 等。而boot-flags 则由boot.efi 自己传给kernel,不需要AptioFix2 进行干预。所以kernel 的内存地址并不是破解而来,而是本来就在这里,也就是说这是苹果系统承认的,没有任何错误的地址。到这时候就不得不提重要的休眠了。之前用了AptioFix 休眠会无法唤醒的原因是,唤醒时系统会寻找并加载 kernel。但是由于kernel 的地址是AptioFix 分配的,boot.efi 和系统并不知道,所以找不到kernel 便无法唤醒。AptioFix2 中则没有这个问题,我们唯一关心的就是加载kernel 这个步骤。
下载:
AptioFix2Test2.zip
(15.14 KB, 下载次数: 1532)
AptioFix2Test3.zip
(15.16 KB, 下载次数: 1397)
这两个文件略有区别。Test3 是纯苹果模式,不基于boot.efi。Test2 是在用了另一种方法,在旧版AptioFix的基础上添加了写入Runtime 到 MemMapIO 的功能(提高对一些主板的兼容性),但是代价就是boot-args 是由AptioFix 接管传给kernel。理论上来说,Test2 比Test3 兼容性更好,用户自己选择适合的版本吧。
*注1:此驱动将不定期更新。
用法:替换原来的AptioFix 后,把boot-args 里的slide=xxx 删除,如果可以正常启用的话就不需要其它设置了。需要休眠请直接进入下面步骤3即可。不需要的话本篇教程就结束了~
如果无法启动,并报memory allocation error(内存分配错误),则需要继续看下面的教程,找到适合自己机器的slide=xxx 参数。
好了,说了这么多,大家应该知道我在讲什么了,剩下的我会在后文慢慢写。
1. 使用AptioFix2 当然就要先找到一块空闲内存才行,不过注意必须是地址大于0x100000 的内存才行。
这里下载UEFI 内存查看器(Mac 下打开):
showbootermemorymap.zip
(1.86 KB, 下载次数: 657)
在结果中找到内存分布图(MemoryMap),类似这样:
- MemoryMap: Size=0xb10, DescriptorSize=48, DescriptorVersion=1
- Type Physical Start - Physical End Number of Pages Virtual Start Attribute
- BS_code 0000000000000000 - 000000000000afff 000000000000000b 0000000000000000 000000000000000f
- available 000000000000b000 - 0000000000066fff 000000000000005c 0000000000000000 000000000000000f
- BS_code 0000000000067000 - 0000000000087fff 0000000000000021 0000000000000000 000000000000000f
- available 0000000000088000 - 000000000008cfff 0000000000000005 0000000000000000 000000000000000f
- BS_data 000000000008d000 - 000000000008ffff 0000000000000003 0000000000000000 000000000000000f
- ACPI_NVS 0000000000090000 - 000000000009ffff 0000000000000010 0000000000000000 0000000000000000
- reserved 00000000000a0000 - 00000000000bffff 0000000000000020 0000000000000000 0000000000000000
- reserved 00000000000f0000 - 00000000000fffff 0000000000000010 0000000000000000 0000000000000000
- BS_code 0000000000100000 - 000000000010ffff 0000000000000010 0000000000000000 000000000000000f
- available 0000000000110000 - 000000000f0fffff 000000000000eff0 0000000000000000 000000000000000f
- LoaderData 000000000f100000 - 000000000f112fff 0000000000000013 0000000000000000 000000000000000f
- available 000000000f113000 - 000000000f1fffff 00000000000000ed 0000000000000000 000000000000000f
- LoaderData 000000000f200000 - 0000000011f71fff 0000000000002d72 0000000000000000 000000000000000f
- ................
复制代码 其中第一列是这一部分内存的作用,这部分内存的开始地址和结束地址就是第二列和第三列了。第四列是内存的页数,也就是内存大小。我们只用关心这些即可。
第一列标注是 avaiable 的表示这部分内存是空闲的,可以被使用。我们的目的就是找到“一大块”空闲内存。(这是dmazar 的原话,我在网上也没有找到到底需要多大)个人认为0xF00 的是可以的,如果越大当然越好,而且地址也是越高越好。在上面列表我们发现最高的符合条件的内存是:
- available 0000000000110000 - 000000000f0fffff 000000000000eff0 0000000000000000 000000000000000f
复制代码
页数达到了0xeff0,肯定是大于0xF00 无疑了。
2. 利用slide=xxx 指向找到的内存地址。
slide 可以理解为跳过内存,通常设置的slide=0 意思就是不跳过内存,从起点开始,因为AptioFix 会自动找到一块内存,无需跳过。但是AptioFix2 是手动设置的,所以必须跳过指向内存前面所有的地址才行。xxx 与地址的转换关系如下:
- 0: kernel 在 0x100000 加载
- 1: 在 0x300000
- ...
- 127: 0xFF00000
复制代码
所以0x110000 < 0x100000 + 0x200000 = 0x300000 就可以了,也就是slide=1。但是实际过程中,由于低地址内存很可能被boot.efi 及其它开机进程占用,所以我们要尽量选个高一点的地址。比如这里我就可以设置slide=50,也就是地址从 0x100000 + 50(0x200000) = 0x6500000 < F0FFFFF。
3. 如何实现休眠唤醒:
因为苹果默认为休眠文件加密,Clover 是无法解密的。所以需要经过一些设置才能破除这无节操的加密文件sleepimage。在这之前不得不提下EmuVariableUefi-64.efi 这个驱动。我们知道UEFI 主板一般都支持NVRAM 保存功能,也就是保存亮度,音量等信息,这样开机后就能还原到和关机前一样的状态。苹果机器也是如此。但是一些主板是没有NVRAM 功能的,这时候EmuVariableUefi 就派上用处了(Emulated Variable 模拟变量)。它能在内存中模拟NVRAM 中所有变量并保存到内存里,在关机时写入到硬盘上,也就是大家熟悉的Nvram.plist 文件。但是这根本不是苹果所设计的。在休眠过程中,内存是处于断电状态,也就是说内存中模拟的NVRAM 将会消失。所以为了避免这个问题,我强烈建议大家能删除EmuVariableUefi 的尽量删除,以达到更接近苹果机的方式。
下面言归正传,破解休眠加密的方法因EmuVariableUefi 存在与否略有不同。
如果你的机器不需要EmuVariableUefi,终端输入:
- sudo pmset -a hibernatemode 57
复制代码 *这是最好的模式,是带休眠预览的。
如果你的机器需要EmuVariableUefi,终端输入:
- sudo pmset -a hibernatemode 29
复制代码 *无休眠预览。
可能有些人好奇上面的数字是怎么来的,我就顺便介绍些hibernatemode 每个数字的意义吧。首先hibernatemode 长度是一个字节,也就是8个2进制数字组成。从苹果官网可以查到某些数字的定义,也就是:
- ____ ___1 (bit 0) 开启休眠,如果为0则是睡眠。
- ____ __1_ (bit 1) 和bit 0 一起使用。当休眠开启后,系统会先进行睡眠,这样能够快速唤醒。但当电量低于临界值时自动断电休眠。这也是苹果默人的方式,安全休眠模式。
- ____ 1___ (bit 3) 利用动态空间管理去除非活跃空间进行休眠,占用更少的空间。
- ___1 ____ (bit 4) 利用动态空间管理去除更多的空间进行休眠,占用更少的空间。
复制代码
后来大神们又从kernel源代码中发现了当hibernatemode 含有0x20(也就是bit 5)时,kernel 才会设定boot-switch-vars。休眠文件加密则是由bit 2 控制,设为1 时会取消加密。
现在我们就可以分析上面hibernatemode 数字的意义了。29 = 0b0001 1101,其中bit 0,2,3,4 全部为1,也就是直接休眠(而不是事先睡眠),并尽量减少睡眠文件的大小,使用不加密的格式。这样Clover 在唤醒时就能直接读取休眠文件,从而实现唤醒。但是缺点是Clover 无法支持休眠预览功能。而boot-switch-vars 必须由EmuVariableUefi 驱动管理,不是kernel,所以bit 5 是0。
推荐的57 = 0b0011 1001,bit 0,3,4,5 设定为1,这样的好处是boot-switch-vars 交给kernel 而不是Clover。休眠文件也可以是加密的,因为唤醒由kernel 完成。
到此为止休眠部分结束!
|
回帖推荐
Hs_Yeah 发表于117楼
查看完整内容
将楼主给出来的几个帖子看了好几天,才知道“休眠预览”的意思。
有“休眠预览”是指:在从休眠醒过来的时候有一个 Apple Logo、一个进度条,还有休眠前的画面做的背景;
如果没有“休眠预览”,则只有一个进度条和黑色背景
-
14
查看全部评分
-
|