再探电源管理-Linux 的休眠模式

理论

计算机中在电源管理中有几种方式达到类似睡眠(suspend)、睡眠(hibernate)以及混合睡眠(hybrid-sleep)。这些模式可以达到在保证唤醒的情况下达到低耗电甚至是无耗电的方式保持运行状态。
对于现代 Linux 来说,这些模式的接口交给了 systemd 来使用。要调用这三种模式可以使用如下来调用:

1
2
3
systemctl suspend       #挂起
systemctl hibernate     #休眠
systemctl hybrid-sleep  #混合睡眠

下面来介绍一下这些模式的具体情况:

挂起(suspend)

挂起是非常常用的模式,在笔记本电脑合盖中默认使用的就是这种方式。挂起在唤醒的时候非常的快,可以很快的进入原来状态,但相对的它耗电量会较高。
事实上,挂起是对除了内存以外的设备断电,仅对内存供电。这样的耗电量已经很低了,但同时唤醒的时候只需要对其他设备供电就能唤醒。实际应用上,除非像一整夜挂起那样长时间的场景,挂起耗电是可以忽略的。(前提是 ACPI 一切正常,不会出现奇奇怪怪问题甚至无法挂起)

休眠(hibernate)

休眠将内存内容保存到硬盘的交换空间(交换分区或交换文件),并完全关机。在启动的时候再将 swap 内容恢复到内存。正因为其完全关机,所以不会耗电,但是关闭和恢复速度较挂起来说较慢(速度取决于硬盘读写速度)。
休眠需要内核、systemd 等进行控制,需要有 swap 分区,因而要求会较高点。

混合睡眠(hybrid-sleep)

如何使用休眠?

创建 swap

如果你在安装时已经有创建 swap 分区并启用,那么无需考虑 swap 分区,要注意的是,swap 大小要达到内存的 1.5 倍到 2 倍才能稳定触发休眠。
那么如果没有提前创建 swap 分区,Linux 还提供了 swap 文件。swap 文件同样可以使用,而且更灵活。下面提供创建的方法:
使用 mkswap 创建 swap 文件,此时 swap 还不会启用。

1
sudo mkswap -U clear --size 48G --file /swapfile

这行命令在 / 下创建了大小为 48G 名为 swapfile 的swap 文件。
启用该 swap 文件。

1
sudo swapon /swapfile

我们还需要保证启动的时候可以自动启用该 swap 分区,较常规的方法是在 /etc/fstab 写入文件信息。

1
/swapfile none swap defaults 0 0

在这之后就可以使用 swap 了,要查看是否正确启用可以使用 free -h查看,输出大致如下:

1
2
3
               total        used        free      shared  buff/cache   available
Mem:            30Gi       9.0Gi        18Gi       2.6Gi       4.8Gi        21Gi
Swap:           47Gi        12Ki        47Gi

这里的 Swap: 就是已经启用的 swap 大小。

配置 initramfs

initramfs 是 Linux 启动过程中很重要的一环,通过 initramfs 启动必要的内核模块并启动全部的用户空间。在 initramfs 配置文件中的 systemd 钩子中添加上休眠所需要的 resume 钩子在 UEFI 下就可以调用休眠。
编辑 /etc/mkinitcpio.conf

未被注释 的HOOKS= 一行中有诸多钩子,而 resume 需要添加在 udev 之后,按照 ArchLinux 建议是在 filesystem 之后 fsck 之前。大致如此:

1
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)

往后需要让内核知道你的 swap 在哪里,但是在现代的 Linux 上(至少现在的 ArchLinux) systemd 会自动找到合适的 swap 并运行休眠。

使用休眠

当运行 systemctl hibernate 后,经过一段不长的时间期间可能会闪亮一下,然后电脑就似乎进入了关机。此时按键盘是无法唤醒的,当在需要唤醒时,像开机一样按下电源键,电脑将进入引导而后开始加载 initramfs 并逐步启动钩子,直到启动 resume hook ,会开始加载休眠镜像。而后,就又回到最初的状态。此时,休眠就完全可用了。

参考资料

  1. ArchLinux wiki - Power management/Suspend and hibernate
  2. ArchLinux wiki - Arch boot process
萌ICP备20241614号