MAC实现睡眠和休眠唤醒
因为苹果默认为休眠文件加密,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 完成。
推荐的59 = 0b0011 1011,bit 0,1,3,4,5 设定为1,这样的好处是boot-switch-vars 交给kernel 而不是Clover,先是睡眠,在经过一段时间之后休眠。休眠文件也可以是加密的,因为唤醒由kernel 完成。
在10.11.x,pmset不能直接修改hibernatemode,如果想自由切换hibernatemode,直接修改/Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist,重新启动即可。
在10.12.x,pmset不能直接修改hibernatemode,如果想自由切换hibernatemode,直接修改/Library/Preferences/com.apple.PowerManagement-xxxxxxxxxxx.plist,重新启动即可。
到此为止休眠部分结束!
在我的x220上,设置hibernatemode=3,standby=1,standbydelay=3600,clover中boot参数增加NeverHibernate=true,这是最好的方式。可能是clover对休眠恢复支持不好,只能禁止这个功能。
一段时间空闲后,机器进入睡眠状态,只有内存带电,电源键灯进入呼吸状态,此时可按Fn健,从睡眠唤醒。
在睡眠状态,经过3600秒后,将内存中的数据写入硬盘后,进入休眠状态,此时机器全部断电,需要按电源键启动,恢复到机器当初工作的状态。
可按Fn+F4直接进入休眠状态。
----------------------------------
macOS的睡眠和休眠
苹果的睡眠指的是仅仅内存供电,电脑可快速唤醒,断电后,所有未保存的数据丢失。
苹果的休眠(安全睡眠或者叫深度睡眠)指的是电脑完全断电,内存中的内容写入磁盘,休眠唤醒后可从磁盘恢复上次工作时的内容,数据不会丢失。
使用的命令是pmset,相关的参数有:
lidwake: 当屏幕掀开的时候唤醒Mac,1是开启 0是关闭
autopoweroff: 如果Mac处于睡眠状态经过指定的时间后,自动把内存数据写入硬盘,并切断所有部件的电源,进入休眠状态,1是开启 0是关闭。但是LZ发现就算是处于开启状态,这个功能也并没有起作用,你可以不管它,也可以关掉
autopoweroffdelay:启用autopoweroff功能的时间,也就是上面说的那个“指定的时间”,单位是秒
standby:功能跟autopoweroff一样,不过仅在hibernatemode为3的时候起作用,1是开启 0是关闭。不过LZ一直没搞明白autopoweroff跟standby有什么不一样,按理说应该是不一样的
standbydelay:启用standby功能的时间,单位也是秒
ttyskeepawake:远程用户正在活动时防止Mac进入睡眠,1是开启 0是关闭
hibernatemode:睡眠模式
darkwakes:这个就是Power Nap,你可以在系统偏好设置里选择开或关,跟在这里设置是一样的,1是开启 0是关闭
hibernatefile:内存镜像存放的地址,这个也可以更改,不过路径必需是root下的路径
displaysleep:Mac闲置多长时间后进入显示器睡眠,2013款Air的系统偏好设置里已经没有这个选项了,Pro是有的,不过其实你可以通过pmset来修改。单位是分钟,这个时间不能长于sleep下设置的时间
sleep:Mac闲置多长时间后进入睡眠,这个系统偏好设置里也有,单位是分钟
acwake:电源改变时唤醒,也就是插上或者拔掉外置电源时唤醒Mac,1是开启 0是关闭
halfdim:显示器睡眠时使显示器亮度改变为当前亮度的一半,1是开启 0是关闭。如果关闭这个功能的话,显示器睡眠会直接关掉显示器。
lessbright:使用电池时使显示器亮度暗一点,系统偏好设置里也有这个,1是开启 0是关闭
disksleep:Mac闲置多长时间后关闭硬盘。这个系统偏好里也有,只不过换了一个字眼—如果可能,使硬盘进入睡眠—勾上这个的话系统就会自动根据sleep的时间设一个合适的时间。单位是秒,这个时间不能长于sleep下设置的时间
sleepservice:LZ还没搞清楚这个是干嘛的,请知道的锋友解释下。
womp:网络远程唤醒,1是开启 0是关闭
networksleep:这个设置影响Mac在睡眠的过程中如何提供网络共享服务,最好就不要动。
要更改某一项设置的话也很简单,打开终端,按下面的格式输入命令:
sudo pmset -# $ &
其中#号有4个参数,分别是:c b u a,作用是表明这个命令修改的是哪个电源设置下的参数。c代表外接电源、b代表电池、u代表UPS、a代表所有电源。
$就是具体的某一项参数,例如你想修改睡眠模式,那就是hibernatemode;修改睡眠闲置时间,是sleep。
&是参数的值
例如你想修改外接电源是Mac的显示器睡眠闲置时间为10分钟,那就输入:
sudo pmset -c displaysleep 10
想修更改所有电源下的硬盘睡眠闲置时间为15分钟,那就是:
sudo pmset -a disksleep 15
比较有兴趣的参数:
hibernatemode
standby
standbydelay
autopoweroff
autopoweroffdelay
这几个参数组成了 OSX 的睡眠模式。
hibernatemode = 0 by default on desktops. The system will not back memory up to persistent storage. The system must wake from the contents of memory; the system will lose context on power loss. This is, historically, plain old sleep.
hibernatemode = 3 by default on portables. The system will store a copy of memory to persistent storage (the disk), and will power memory during sleep. The system will wake from memory, unless a power loss forces it to restore from hibernate image.
hibernatemode = 25 is only settable via pmset. The system will store a copy of memory to persistent storage (the disk), and will remove power to memory. The system will restore from disk image. If you want "hibernation" - slower sleeps, slower wakes, and better battery life, you should use this setting.
standby causes kernel power management to automatically hibernate a machine after it has slept for a specified time period. This saves power while asleep. This setting efaults to ON for supported hardware. The setting standby will be visible in pmset -g if the feature is supported on this machine.
standbydelay specifies the delay, in seconds, before writing the hibernation image to disk and powering off memory for Standby.
autopoweroff is enabled by default on supported platforms as an implementation of Lot 6 to the European Energy-related Products Directive. After sleeping for <autopoweroffdelay> seconds, the system will write a hibernation image and go into a lower power chipset sleep. Wakeups from this state will take longer than wakeups from regular sleep.
autopoweroffdelay specifies the delay, in seconds, before entering autopoweroff mode.
可见,Apple 的安全睡眠其实是个统称,具体是由2个参数激发的,这2个参数都可以在普通睡眠一段时间后让电脑进入深度睡眠状态。
对于平常的使用,建议设置
sudo pmset -a hibernatemode 3
sudo pmset -a standby 1
sudo pmset -a standbydelay 1800
这样电脑在睡眠1800秒之后,内存中的数据全部会保存到硬盘,然后进入休眠,下次启动后可恢复到原先的工作状态。
当然如果你不想将内存中的数据写入硬盘,可以如下设置:
sudo pmset -a hibernatemode 0
sudo pmset -a autopoweroff 0
sudo pmset -a standby 0
sudo rm /var/vm/sleepimage
然后不管你怎么重启,睡眠n久,都不会再生成内存镜像文件了,当然你的电脑就无法再进入深度睡眠模式,Apple 官方说电池待机能力可能会稍稍降低,但我看也未必,普通睡眠状态下电压已经非常小了。
另外,Clover启动sleepimage文件似乎并不是特别的好,可以对Clover中boot参数增加NeverHibernate=true,禁止这个功能。从Clover重新启动后,仍然能够恢复到原先的工作内容。
在X220中的实验结果,设置:
sudo pmset -a hibernatemode 3
sudo pmset -a standby 1
sudo pmset -a standbydelay 1800
Clover中boot参数增加NeverHibernate=true
睡眠、休眠正常,从Clover启动后,恢复睡眠前的工作内容。并且可以直接按Fn+F4直接进入休眠,此时电源灯停止呼吸,电脑全部断电,按电源键恢复原先的工作内容。
如果各位对Clover的休眠恢复,有什么好的建议,可以跟帖回复。
谢谢!