2023年12月5日发(作者:)

linux中ACPI电源管理G状态、S状态、D状态、C状态、P状态

ACPI 高级电源管理

ACPI 中定义了 G、D、S、C、P 这 5 个大的电力状态。

G 状态 Global system state

G 状态表示的是用户看到的整个系统的电力状态。

G0 运行模式。向硬件提供电源,软件可以运行的状态。

G1 停止模式。所谓的待机或休眠状态。

G2 软件为关闭状态,应将消耗若干电力状态。

G3 系统完全关闭,电源关闭的状态。

S 状态

S0 运行模式,与 G0 相同。

S1 到恢复为止的延迟时间较少的停止模式。 CPU 的上下文不会丢失。

S2 丢失 CPU 和系统缓存上下文。这些上下文需要在系统唤醒时进行恢复。在 Linux 中与 S3 相同。

S3 丢失除软件以外的系统上下文。这些上下文需要在操作系统唤醒时进行恢复。

S4 最省电。到恢复为止花费时间最多的停止模式。停止向所有设备提供电源

S5 除了不保存上下文以外,其它与 S4 相同。 S5 在恢复时进行的处理与普通的操作系统相同。与 G2 含义相同。

D 状态

Device Power State 定义的是各个设备的电力状态,设备的状态有如下内容:

耗电量

保存设备内寄存器上下文的状态

直到设备驱动程序可使用为止必须进行的操作量

直到设备可使用为止需要的时间

不同的子状态描述如下:

D0 设备可以完全运行的状态。所有上下文全部有效,最耗电。

D1 对于每个设备的意义不同。一般来说,耗电量比 D0 少,丢失的上下文比 D2 更少

D2 对于每个设备类型的意义也不同。一般来说,耗电量比 D1 更少,丢失的上下文比 D1 更多。

D3hot 对于每个设备类型的意义不同。D3hot 状态的设备主电源开启,可以从软件访问设备。但上下文是否能保留取决于实际安装的

设备。D3 设备电源完全断开的状态。设备的上下文全部丢失,到恢复为止花的时间最长。在 PCI 用语中称为 D3cold。PCI 中常常将

D3hot 与 D3cold 统称为 D3

C 状态

Processor Power State 是 G0 中 CPU 空闲时进行的省电模式。

C0 运行中的状态。通常的运行模式。

C1 CPU 停止状态。使用 hlt 命令停止 CPU 的时钟,到恢复为止几乎没有延迟时间,软件不需进行特殊处理。

C2 总线的时钟也停止。恢复所花费的最长延时时间传递给 ACPI 的固件,操作系统基于这个延时时间判断使用 C1 还是 C2。

C3 将花费时间最长的延迟传递给 ACPI 固件,操作系统使用这个延迟时间判断使用 C2 还是 C3。操作系统需要考虑缓存的同步。

使用 C 状态时要注意,C 状态的程度越深,恢复到 C0 状态所需的时间越长。

P 状态

全称为 Device and Processor Performance State

P 状态是以控制电量消耗来降低设备或 CPU 的性能,对 D0 状态的设备、C0 状态的 CPU 进行了更细致的划分。

P0 通常的模式。以最高性能、最大耗电量运行。

P1 运行在低于最高性能、最大耗电量的模式 Pn n 的值越大,性能和耗电量越低。

ACPI 的结构

1. ACPI 系统描述表

2. ACPI 寄存器

3. ACPI BIOS

ACPI 描述表在 ACPI 的接口中是核心的组件,提供 ACPI 寄存器等信息。ACPI BIOS 可以 提供 ACPI 系统描述表以及启动、停止、唤醒

等功能。

两个编程模型

ACPI 的硬件模型有下面两种:

固定硬件编程模型

使用 ACPI 中定义的寄存器来访问 ACPI 的功能。

通用硬件编程模型

各厂商可以使用 ACPI Machine Language 将硬件固有的处理安装到 BIOS 中。操作系统可 以通过分析 BIOS 提供的 AML 代码,来理解就餐器的地址和访问方

法等。

AML 是二进制码,通过编译 ACPI Source language 来生成。操作系统分析 AML 将 AML中 所写的内容按照解释器来执行。

ACPI 系统描述表

可以通过 pmtools 与 iasl 相关的命令来查看。执行如下命令安装这两个程序:

sudo apt-get install pmtools sudo apt-get install iasl

运行示例如下:

root@debian:~# acpidump -b -o

root@debian:~# ls

root@debian:~# ls root@debian:~#

root@debian:~# iasl -d

Intel ACPI Component Architecture

ASL+ Optimizing Compiler/Disassembler version 20181213

Copyright (c) 2000 - 2018 Intel Corporation

Input file , Length 0x1368A (79498) bytes

ACPI: DSDT 0x0000 01368A (v01 PTLTD Custom 06040000 MSFT 03000001)

Pass 1 parse of [DSDT]

Pass 2 parse of [DSDT]

Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)

Parsing completed

Disassembly completed

ASL Output: - 729339 bytes

root@debian:~# head -n 30

/*

* Intel ACPI Component Architecture

* AML/ASL+ Disassembler version 20181213 (64-bit version)

* Copyright (c) 2000 - 2018 Intel Corporation

*

* Disassembling to symbolic ASL+ operators

*

* Disassembly of , Mon Aug 10 12:43:44 2020

*

* Original Table Header:

* Signature "DSDT"

* Length 0x0001368A (79498)

* Revision 0x01 **** 32-bit table (V1), no 64-bit math support

* Checksum 0x63

* OEM ID "PTLTD "

* OEM Table ID "Custom "

* OEM Revision 0x06040000 (100925440)

* Compiler ID "MSFT"

* Compiler Version 0x03000001 (50331649)

*/

DefinitionBlock ("", "DSDT", 1, "PTLTD ", "Custom ", 0x06040000)

{

External (_SB_.L1M0.L0MX, IntObj)

External (_SB_.L1M1.L0MX, IntObj)

External (_SB_.L1M2.L0MX, IntObj)

External (_SB_.L1M3.L0MX, IntObj)

External (_SB_.L1M4.L0MX, IntObj)

External (_SB_.L1M5.L0MX, IntObj)

External (_SB_.L1M6.L0MX, IntObj)

External (_SB_.L1M7.L0MX, IntObj)

使用 ACPI 的 S 状态

查看支持的 S 状态:

root@debian:~# cat /sys/power/state

freeze standby mem disk

standby S1 mem S3 disk S4

切换状态:

echo "状态字符串" > /sys/power/state

执行示例:

root@debian:~# echo "mem" > /sys/power/state

按下电源键就可以恢复。

S3 状态的结构

使用 S3 状态时,不同系统的反应不同,大致操作如下:

停止进程

停止设备运行

将唤醒时的开始地址作为 Wakeup vector 登录到 BIOS

停止 BSP (Boot Strap Processor) 以外的 CPU 运行

停止系统设备运行

保存内核和 CPU 的状态

将获取到的 ACPI 的 _S3 对象得到的值写入 FADT 的 PM1 寄存器,进入待机模式。

系统恢复时,从登录到 wakeup vector 的地址启动,按下列方式恢复到待机前的状态

启用 ACPI

恢复系统设备

启用 CPU

清除 wakeup vector

恢复停止的设备

恢复进程

S4 状态的使用方法

linux 中 S4 称为 swap 待机,有内核的 S4 处理通过将内存上的所有数据保存在交换区磁盘来停止电源,恢复时由 bootloader 启动内

核,在内核初始化时,把之前保存到交换区磁盘的数据读入内存来快速回复到原来的状态。

使用方法如下:

echo "platform" > /sys/power/disk

echo "disk" > /sys/power/state

休眠要使用交换区磁盘,一般需要准备内存的 1.5 ~ 2 倍的磁盘容量。这应该就是 swap 要设置为 2 倍内存大小的原因。

在我的系统中,默认保存在交换区磁盘的内存大小如下:

longyu@debian:~$ cat /sys/power/image_size 814505984

执行如下命令来取消限制。

echo "0" > /sys/power/image_size

执行一次休眠后按电源键重新启动系统后查看 dmesg 信息,有如下相关信息:

[ 759.283304] PM: hibernation entry

[ 759.285989] PM: Syncing filesystems ...

[ 759.289551] PM: done.

[ 759.289552] Freezing user space processes ... (elapsed 0.001 seconds) done.

[ 759.291357] OOM killer disabled.

[ 759.291465] PM: Marking nosave pages: [mem 0x00000000-0x00000fff]

[ 759.291466] PM: Marking nosave pages: [mem 0x0009e000-0x000fffff]

[ 759.291467] PM: Marking nosave pages: [mem 0x7fee0000-0x7fefffff]

[ 759.291468] PM: Basic memory bitmaps created

[ 759.291505] PM: Preallocating done (allocated 95921 pages)

[ 759.339329] PM: Allocated 383684 kbytes in 0.04 seconds (9592.10 MB/s)

[ 759.339330] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.

[ 759.342363] Suspending console(s) (use no_console_suspend to debug)[ 759.342363] Suspending console(s) (use no_console_suspend to debug)[ 759.343092] serial 00:05: disabled[ 759.376353] mptbase: ioc0: pci-suspend: pdev=0xa726cd, slot=0000:00:10.0, Entering operating state [D0][ 759.457082] ACPI: Preparing to enter system sleep state S4[ 759.457366] PM: Saving platform NVS memory[ 759.457368] Disabling non-boot CPUs ...[ 759.494741] smpboot: CPU 1 is now offline[ 759.522630] smpboot: CPU 2 is now offline[ 759.550458] smpboot: CPU 3 is now offline[ 759.583388] smpboot: CPU 4 is now offline[ 759.606987] smpboot: CPU 5 is now offline[ 759.625346] smpboot: CPU 6 is now offline[ 759.653837] smpboot: CPU 7 is now offline[ 759.655801] PM: Creating hibernation image:[ 759.682494] PM: Need to copy 90196 pages[ 759.682497] PM: Normal pages needed: 90196 + 1024, available pages: 433921[.256268] PM: Restoring platform NVS memory[.257563] Enabling non-boot CPUs ...[.257640] x86: Booting SMP configuration:[.257640] smpboot: Booting Node 0 Processor 1 APIC 0x1[.258291] Disabled fast string operations[.258509] cache: parent cpu1 should not be sleeping[.258972] CPU1 is up[.258998] smpboot: Booting Node 0 Processor 2 APIC 0x2[.259670] Disabled fast string operations[.259845] cache: parent cpu2 should not be sleeping[.260236] CPU2 is up[.260272] smpboot: Booting Node 0 Processor 3 APIC 0x3[.260877] Disabled fast string operations[.261022] cache: parent cpu3 should not be sleeping[.261423] CPU3 is up[.261443] smpboot: Booting Node 0 Processor 4 APIC 0x4[.262117] Disabled fast string operations[.262547] cache: parent cpu4 should not be sleeping[.263934] CPU4 is up[.263991] smpboot: Booting Node 0 Processor 5 APIC 0x5[.264913] Disabled fast string operations[.265184] cache: parent cpu5 should not be sleeping[.265796] CPU5 is up[.265821] smpboot: Booting Node 0 Processor 6 APIC 0x6[.266459] Disabled fast string operations[.266673] cache: parent cpu6 should not be sleeping[.267193] CPU6 is up[.267219] smpboot: Booting Node 0 Processor 7 APIC 0x7[.267894] Disabled fast string operations[.268043] cache: parent cpu7 should not be sleeping[.268521] CPU7 is up[.269975] ACPI: Waking up from system sleep state S4[.325536] mptbase: ioc0: pci-resume: pdev=0xa726cd, slot=0000:00:10.0, Previous operating state [D0][.325631] mptbase: ioc0: pci-resume: ioc-state=0x1,doorbell=0x14000000[.325631] mptbase: ioc0: Sending mpt_do_ioc_recovery[.325632] mptbase: ioc0: Initiating bringup[.325634] [drm] width 640[.325639] [drm] height 480[.325643] [drm] bpp 32[.327033] [drm] Fifo max 0x00040000 min 0x00001000 cap 0x0000077f[.327785] [drm] Using command buffers with DMA pool.[.328515] usb usb2: root hub lost power or was reset[.330434] serial 00:05: activated[.331200] usb usb1: root hub lost power or was reset[.331518] ehci-pci 0000:02:03.0: cache line size of 64 is not supported[.389402] e1000: ens38 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None[.423015] ioc0: LSI53C1030 B0: Capabilities={Initiator}[.662087] mptbase: ioc0: pci-resume: success[.696571] usb 2-2: reset full-speed USB device number 3 using uhci_hcd[ 0.267194] usb 2-1: reset full-speed USB device number 2 using uhci_hcd

[ 0.267194] usb 2-1: reset full-speed USB device number 2 using uhci_hcd

[ 0.433369] PM: Basic memory bitmaps freed

[ 0.433370] OOM killer enabled.

[ 0.433370] Restarting tasks ... done.

[ 0.436577] PM: hibernation exit

PM: hibernation entry 与 PM: hibernation exit 之间就是休眠过程的处理。

有的 PC 上可能出现 BIOS 无法顺利运行,休眠失败的情况,这时可以尝试如下方法:

1. 编辑 内核启动参数中添加用于恢复系统的交换设备 “resume=<交换设备名称>” 如 resume=/dev/sda1

2. 执行如下敏玲将休眠设置为 shutdown 模式

echo shutdown > /sys/power/disk

3. 进行休眠

echo disk > /sys/power/state

如果恢复系统后系统运行状态有所不同,有时会通过将交换区的数据强制读入内存来改善性能,这可以通过执行如下命令来完成:

swapoff -a

swapon -a

如果休眠失败,可以查看 /var/log/messages 文件来寻找原因。