系统睡眠状态 【ChatGPT】

发布时间 2023-12-12 10:48:31作者: 摩斯电码

系统睡眠状态

版权 © 2017 Intel Corporation

作者 Rafael J. Wysocki rafael.j.wysocki@intel.com

支持的睡眠状态

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

挂起到空闲(Suspend-to-Idle)

这是一种通用的、纯软件的、轻量级的系统挂起变体(也称为S2I或S2Idle)。相对于运行时空闲,它允许更多的能量被保存,通过冻结用户空间、挂起时间跟踪和将所有I/O设备置于低功耗状态(可能比工作状态下的功耗更低),使处理器在系统挂起期间可以进入其最深的空闲状态。

系统从这种状态唤醒是通过内部中断,因此理论上任何可以在工作状态下生成中断的设备也可以被设置为S2Idle的唤醒设备。

这种状态可以在不支持待机或挂起到RAM的平台上使用,或者可以与任何更深的系统挂起变体一起使用,以提供减少的恢复延迟。如果设置了CONFIG_SUSPEND内核配置选项,则始终支持此状态。

待机(Standby)

如果支持,此状态提供适度但实际的能量节省,同时提供相对简单的返回工作状态的过渡。没有丢失操作状态(系统核心逻辑保持电源),因此系统可以很容易地返回到离开的状态。

除了冻结用户空间、挂起时间跟踪和将所有I/O设备置于低功耗状态(这也适用于挂起到空闲),在转换到此状态期间,非启动CPU被下线,并且在这种状态下所有低级系统功能都被挂起。因此,相对于挂起到空闲,它应该允许更多的能量被保存,但恢复延迟通常会大于该状态。

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

如果在ACPI-based系统上支持此状态,则此状态将映射到ACPI定义的S1系统状态。

挂起到RAM(Suspend-to-RAM)

如果支持,此状态(也称为STR或S2RAM)可以提供显着的能量节省,因为系统中的所有内容都被置于低功耗状态,除了内存,内存应该被置于自刷新模式以保留其内容。在进入待机时执行的所有步骤也会在转换到S2RAM时执行。根据平台的能力,可能会执行其他操作。特别是,在基于ACPI的系统上,内核在S2RAM转换期间将控制权传递给平台固件(BIOS),通常会导致关闭一些不受内核直接控制的更多低级组件的电源。

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

在基于ACPI的系统上,S2RAM需要平台固件中的一些最小引导代码来从中恢复系统。在其他平台上也可能是这种情况。

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

如果在ACPI-based系统上支持S2RAM,则必须设置CONFIG_SUSPEND内核配置选项,并且支持必须由平台在核心系统挂起子系统中注册。在ACPI-based系统上,它映射到ACPI定义的S3系统状态。

休眠(Hibernation)

如果支持,此状态(也称为挂起到磁盘或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" 分别代表待机和挂起到RAM。

    将这个文件中列出的字符串之一写入,会导致系统挂起变体与 state 文件中的 "mem" 字符串相关联。当前与 state 文件中的 "mem" 字符串相关联的挂起变体字符串将显示在方括号中。

    如果内核不支持系统挂起,那么这个文件就不存在。

  • disk

    这个文件控制休眠(挂起到磁盘)后的操作模式,告诉内核在创建休眠镜像后该如何处理。

    从中读取会返回一系列支持的选项,包括:

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

    • shutdown:关闭系统。

    • reboot:重新启动系统(主要用于诊断)。

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

    • test_resume:诊断操作。加载镜像,就好像系统刚从休眠中醒来,当前运行的内核实例是一个恢复内核,并随后进行完整的系统恢复。

    将上述字符串之一写入该文件会选择相应的选项。

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

    如果内核不支持休眠,那么这个文件就不存在。

  • image_size

    这个文件控制休眠镜像的大小。可以写入一个表示非负整数的字符串,作为镜像大小的最大限制,单位为字节。休眠核心将尽最大努力确保镜像大小不超过该数字,但如果这是不可能实现的,仍将创建休眠镜像,并使其尺寸尽可能小。特别地,将 '0' 写入该文件会使休眠镜像的大小最小化。

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

  • pm_trace

    这个文件控制“PM跟踪”机制,将最后一个挂起或恢复事件点保存在RTC内存中,跨重启保留。它有助于更有效地调试由于系统挂起或恢复期间设备驱动程序故障而导致的硬锁定或重启。

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

    它默认为 "0",可以通过将表示非零整数的字符串写入其中来更改为 "1"。

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

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