系统睡眠状态

版权:

© 2017 英特尔公司

作者:

Rafael J. Wysocki <rafael.j.wysocki@intel.com>

睡眠状态是整个系统的全局低功耗状态,在此状态下用户空间代码无法执行,并且系统整体活动显著减少。

可支持的睡眠状态

根据其配置和所运行平台的能力,Linux 内核最多可支持四种系统睡眠状态,包括休眠和最多三种系统挂起变体。内核可支持的睡眠状态如下所示。

挂起到空闲

这是一种通用的、纯软件的、轻量级系统挂起变体(也称为 S2I 或 S2Idle)。通过冻结用户空间、暂停计时以及将所有 I/O 设备置于低功耗状态(可能比工作状态下的功耗更低),它可以比运行时空闲状态节省更多能源,从而使处理器在系统挂起时可以在其最深层的空闲状态下花费时间。

系统通过带内中断从该状态唤醒,因此理论上,任何在工作状态下能产生中断的设备,也可以设置为 S2Idle 的唤醒设备。

该状态可用于不支持待机挂起到内存的平台,或者作为任何更深层系统挂起变体的补充以减少唤醒延迟。如果设置了CONFIG_SUSPEND内核配置选项,则始终支持该状态。

待机

如果支持此状态,它能提供适度但实际的节能效果,同时提供相对直接的返回工作状态的转换。没有操作状态丢失(系统核心逻辑保留电源),因此系统可以轻松地回到之前的状态。

除了冻结用户空间、暂停计时和将所有 I/O 设备置于低功耗状态(挂起到空闲也执行此操作)之外,在转换到此状态期间,非引导 CPU 会离线,并且所有低级系统功能都会暂停。因此,与挂起到空闲相比,它应该能节省更多能源,但唤醒延迟通常会大于该状态。

能够从该状态唤醒系统的设备集通常相对于挂起到空闲有所减少,并且可能需要依靠平台来适当设置唤醒功能。

如果设置了CONFIG_SUSPEND内核配置选项并且平台已向核心系统挂起子系统注册了对其的支持,则支持此状态。在基于 ACPI 的系统上,此状态映射到 ACPI 定义的 S1 系统状态。

挂起到内存

如果支持此状态(也称为 STR 或 S2RAM),它能显著节能,因为系统中除内存外的一切都进入低功耗状态,内存应置于自刷新模式以保留其内容。进入待机时执行的所有步骤在转换到 S2RAM 期间也会执行。根据平台功能,可能会进行额外操作。特别是,在基于 ACPI 的系统上,内核在 S2RAM 转换的最后一步将控制权交给平台固件 (BIOS),这通常会导致关闭一些不受内核直接控制的低级组件。

设备和 CPU 的状态保存在内存中。所有设备都已挂起并进入低功耗状态。在许多情况下,进入 S2RAM 时所有外围总线都会断电,因此设备必须能够处理返回“开”状态的转换。

在基于 ACPI 的系统上,S2RAM 需要平台固件中一些最少的引导代码才能从中恢复系统。其他平台也可能如此。

能够从 S2RAM 唤醒系统的设备集通常相对于挂起到空闲待机有所减少,并且可能需要依靠平台来适当设置唤醒功能。

如果设置了CONFIG_SUSPEND内核配置选项并且平台已向核心系统挂起子系统注册了对其的支持,则支持 S2RAM。在基于 ACPI 的系统上,它映射到 ACPI 定义的 S3 系统状态。

休眠

此状态(也称为挂起到磁盘或 STD)提供了最大的节能效果,即使在缺乏对系统挂起的低级平台支持的情况下也可以使用。但是,它需要底层 CPU 架构存在一些用于恢复系统的低级代码。

休眠与任何系统挂起变体都显著不同。它需要三次系统状态更改才能进入休眠,两次系统状态更改才能恢复。

首先,当触发休眠时,内核会停止所有系统活动,并创建内存快照图像以写入持久存储。接下来,系统进入一个可以保存快照图像的状态,图像被写入,最后系统进入目标低功耗状态,其中几乎所有硬件组件(包括内存)的电源都被切断,除了有限的唤醒设备集。

快照图像写入完成后,系统可以进入特殊的低功耗状态(如 ACPI S4),或者直接断电。断电意味着最小的功耗,并且允许此机制在任何系统上工作。但是,进入特殊的低功耗状态可能会允许使用额外的系统唤醒方式(例如,按下键盘上的键或打开笔记本电脑盖)。

唤醒后,控制权交给平台固件,该固件运行引导加载程序,引导加载程序启动内核的新实例(控制权也可以直接转到引导加载程序,具体取决于系统配置,但无论如何,它都会导致启动内核的新实例)。内核的这个新实例(称为恢复 内核)在持久存储中寻找休眠图像,如果找到,则将其加载到内存中。接下来,系统中所有活动停止,恢复内核用图像内容覆盖自身,并跳到存储在图像中的原始内核中的特殊跳板区域(称为图像 内核),这里需要特殊的架构特定的低级代码。最后,图像内核将系统恢复到休眠前的状态,并允许用户空间再次运行。

如果设置了CONFIG_HIBERNATION内核配置选项,则支持休眠。但是,只有当给定 CPU 架构的支持包含用于系统恢复的低级代码时,才能设置此选项。

系统挂起和休眠的基本 sysfs 接口

电源管理子系统为用户空间提供了一个统一的sysfs接口,用于系统睡眠,无论底层系统架构或平台如何。该接口位于/sys/power/目录中(假设sysfs挂载在/sys),它由以下属性(文件)组成

state

此文件包含一个字符串列表,表示内核支持的睡眠状态。将这些字符串之一写入此文件会使内核开始将系统转换为该字符串所代表的睡眠状态。

特别是,“disk”、“freeze”和“standby”字符串分别代表休眠挂起到空闲待机睡眠状态。“mem”字符串根据下面描述的mem_sleep文件的内容进行解释。

如果内核不支持任何系统睡眠状态,则此文件不存在。

mem_sleep

此文件包含一个字符串列表,表示支持的系统挂起变体,并允许用户空间选择与上述state文件中的“mem”字符串关联的变体。

此文件中可能存在的字符串是“s2idle”、“shallow”和“deep”。“s2idle”字符串始终代表挂起到空闲,并且按照惯例,“shallow”和“deep”分别代表待机挂起到内存

将列出的字符串之一写入此文件,会导致其所代表的系统挂起变体与state文件中的“mem”字符串关联。当前与state文件中的“mem”字符串关联的挂起变体字符串显示在方括号中。

如果内核不支持系统挂起,则此文件不存在。

disk

此文件控制休眠(挂起到磁盘)的操作模式。具体来说,它告诉内核在创建休眠图像后该怎么做。

从中读取会返回一个支持的选项列表,编码为

平台

将系统置于特殊的低功耗状态(例如 ACPI S4),以提供额外的唤醒选项,并可能允许平台固件在唤醒后采用简化的初始化路径。

仅当平台提供特殊机制在创建休眠图像后将系统置于睡眠状态时(例如,具有 ACPI 的平台通常会这样做)才可用。

关机

关闭系统电源。

重启

重启系统(主要用于诊断)。

挂起

混合系统挂起。将系统置于通过上述mem_sleep文件选择的挂起睡眠状态。如果系统成功从该状态唤醒,则丢弃休眠图像并继续。否则,使用图像恢复系统先前的状态。

如果支持系统挂起,则此选项可用。

test_resume

诊断操作。加载图像,就像系统刚从休眠中唤醒,并且当前运行的内核实例是恢复内核一样,然后进行完整的系统恢复。

将上面列出的字符串之一写入此文件,会导致选择其所代表的选项。

当前选定的选项显示在方括号中,这意味着当通过向/sys/power/state写入disk触发休眠时,将创建并保存图像后执行其所代表的操作。

如果内核不支持休眠,则此文件不存在。

image_size

此文件控制休眠图像的大小。

可以向其写入一个表示非负整数的字符串,该整数将用作图像大小的尽力而为的上限(以字节为单位)。休眠核心将尽力确保图像大小不超过该数字,但如果无法实现,仍将创建休眠图像,并且其大小将尽可能小。特别是,向此文件写入“0”会导致休眠图像的大小最小。

从中读取会返回当前图像大小限制,默认情况下,该限制设置为可用 RAM 大约 2/5。

pm_trace

此文件控制“PM 跟踪”机制,该机制在重启后将上次挂起或恢复事件点保存在 RTC 内存中。它有助于更有效地调试在系统挂起或恢复期间(这种情况更常见)由于设备驱动程序故障导致的硬锁定或重启。

如果它包含“1”,则每个挂起/恢复事件点的指纹将依次存储在 RTC 内存中(覆盖实际的 RTC 信息),因此如果在存储后立即发生系统崩溃,它将幸存下来,并且以后可以用于识别导致崩溃的驱动程序。

它默认包含“0”,可以通过向其中写入一个表示非零整数的字符串来将其更改为“1”。

根据上述内容,有两种方法可以让系统进入挂起到空闲状态。第一种是直接将“freeze”写入/sys/power/state。第二种是将“s2idle”写入/sys/power/mem_sleep,然后将“mem”写入/sys/power/state。同样,如果平台支持待机状态,也有两种方法可以让系统进入该状态(在这种情况下写入控制文件的字符串分别是“standby”或“shallow”以及“mem”)。然而,只有一种方法可以让系统进入挂起到内存状态(将“deep”写入/sys/power/mem_sleep,将“mem”写入/sys/power/state)。

默认的挂起变体(即无需向/sys/power/mem_sleep写入任何内容即可使用的变体)是“deep”(在大多数支持挂起到内存的系统上)或“s2idle”,但可以通过内核命令行中的mem_sleep_default参数值来覆盖。在某些具有 ACPI 的系统上,根据 ACPI 表中的信息,即使原则上支持挂起到内存,默认值也可能是“s2idle”。