ACPI电源按钮唤醒S3切换到S0流程(附流程图)
- [1 完整软硬件流程(S3 → S0)](#1 完整软硬件流程(S3 → S0))
-
- [第一阶段:硬件触发唤醒(物理层 → 芯片组 → 寄存器)](#第一阶段:硬件触发唤醒(物理层 → 芯片组 → 寄存器))
- 第二阶段:固件早期恢复(BIOS/UEFI)
- 第三阶段:OS内核重入(恢复执行上下文)
- 第四阶段:AML执行与设备恢复
- 第五阶段:软件恢复完成
- [2 完整流程图](#2 完整流程图)
- [3 关键寄存器与控制方法速查](#3 关键寄存器与控制方法速查)
本文属于《 ACPI规范基础系列教程》之一,欢迎查看其它文章。
在 S3(挂起到内存 / Suspend to RAM) 状态下,系统仅保留内存供电,其余硬件(如CPU、硬盘、外设等)断电。唤醒S3并恢复到 S0(工作状态) 的主要方式如下:
常见唤醒途径
- 按下电源按钮:这是最常见且广泛支持的方式,适用于绝大多数支持S3的设备 。
- 外接键盘或鼠标输入:若系统BIOS/UEFI和驱动配置允许,按任意键或移动鼠标可触发唤醒 。
- 网络唤醒(WOL, Wake-on-LAN):
- 需主板和网卡支持;
- 路由器需配置端口转发(通常UDP 7或9端口);
- 客户端发送"Magic Packet"唤醒包 。
- USB设备唤醒:部分USB设备(如键盘、鼠标)在S3下仍可发送唤醒信号,前提是其在设备管理器中启用了"允许此设备唤醒计算机"选项 。
- 定时器唤醒:通过操作系统设置唤醒定时器(如计划任务),可在指定时间自动唤醒。
与休眠流程(S0->S3)类似,唤醒流程也分为固定硬件 和通用事件 两种路径,下面以更标准的固定硬件方案为主线进行说明。
1 完整软硬件流程(S3 → S0)
第一阶段:硬件触发唤醒(物理层 → 芯片组 → 寄存器)
此时系统处于S3状态,CPU停止执行,内存自刷新,但芯片组的唤醒逻辑和部分待机电源仍在工作。
- 用户按下电源按钮:产生物理信号。
- EC捕获并转发 :嵌入式控制器检测到按钮按下,向芯片组的
PWRBTN#专用引脚发送一个低脉冲。 - 芯片组唤醒逻辑启动 :
- 芯片组检测到
PWRBTN#信号。 - 寄存器操作: 芯片组硬件将PM1状态寄存器 中的
PWRBTN_STS(电源按钮状态)位 置为1,记录唤醒事件源。 - 寄存器操作: 芯片组硬件将PM1状态寄存器 中的
WAK_STS(唤醒状态)位 置为1,表示系统从睡眠状态唤醒。
- 芯片组检测到
- 硬件恢复电源 :
- 芯片组解除
SLP_S3#信号的断言(assertion),主电源轨恢复供电。 - CPU接收
POWER GOOD信号,从重置向量开始执行。
- 芯片组解除
第二阶段:固件早期恢复(BIOS/UEFI)
此时CPU开始在实模式下执行固件代码。
- BIOS早期初始化 :快速初始化内存控制器、芯片组等必要部分,但不破坏内存中的内容。
- 检测唤醒源(固件视角) :
- BIOS读取PM1状态寄存器,发现
WAK_STS位 为1,确认是从S3唤醒,而非冷启动。 - (可选)BIOS可以读取
PWRBTN_STS位,确认具体的唤醒原因。
- BIOS读取PM1状态寄存器,发现
- 查找OS唤醒向量 :
- BIOS读取FACS 表中的
FIRMWARE_WAKING_VECTOR,这个地址是操作系统在休眠前写入的,指向OS唤醒代码的入口。
- BIOS读取FACS 表中的
- 跳转到OS:BIOS执行远跳转,进入OS的实模式唤醒代码。
第三阶段:OS内核重入(恢复执行上下文)
此时CPU进入OS的实模式唤醒代码,准备恢复执行。
- OS唤醒代码开始执行 :入口点通常是
wakeup.S,CPU处于实模式。 - 恢复CPU运行环境 :
- 代码通过
ljmpl指令切换回保护模式。 - 恢复休眠前保存的GDT、IDT和寄存器状态。
- 代码通过
- 从休眠函数返回 :
- 当CPU状态完全恢复后,代码从
do_suspend_lowlevel()返回,看起来就像是从acpi_enter_sleep_state()函数正常返回一样。 - 重新获取内核锁,恢复中断处理。
- 当CPU状态完全恢复后,代码从
第四阶段:AML执行与设备恢复
此时内核已恢复基本运行,开始与ACPI固件交互并恢复设备。
- 调用_WAK方法 :
- 内核调用ACPI控制方法
_WAK,将唤醒状态作为参数传入。 _WAK方法由BIOS提供,执行平台特定的唤醒后操作(如重新配置EC、恢复某些GPIO状态)。
- 内核调用ACPI控制方法
- OS确定唤醒源(OSPM视角) :
- 寄存器操作: OS读取PM1状态寄存器,发现
PWRBTN_STS位 为1,确认是电源按钮唤醒了系统。 - 寄存器操作: OS软件向PM1状态寄存器
PWRBTN_STS位写入1,清除该状态位,表示事件已处理。 - 寄存器操作: OS软件向PM1状态寄存器
WAK_STS位写入1,清除唤醒状态标志。
- 寄存器操作: OS读取PM1状态寄存器,发现
- 恢复设备驱动 :
- 内核遍历设备树,为每个设备调用注册的resume回调函数。
- 设备驱动恢复硬件状态,重新初始化寄存器。
- 恢复控制台和中断:重新启用控制台输出,恢复所有中断。
第五阶段:软件恢复完成
- 解冻用户空间:内核解冻之前冻结的用户进程和内核线程。
- 返回用户空间:系统完全恢复到S0工作状态,看起来就像系统只是"暂停"了一下。
2 完整流程图
下面是根据上述流程,绘制的完整流程图:

3 关键寄存器与控制方法速查
为方便理解软硬件,以下是流程中涉及的寄存器/方法及其作用:
| 名称 | 类型 | 作用 | 所在位置 |
|---|---|---|---|
| SLP_S3# | 硬件信号 | S3期间有效(低电平),唤醒时解除 | 芯片组引脚 |
| FACS | ACPI表 | 包含Firmware Waking Vector | 内存中,由FADT指向 |
| FIRMWARE_WAKING_VECTOR | FACS字段 | BIOS跳转到OS唤醒代码的地址 | FACS偏移12 |
| X_FIRMWARE_WAKING_VECTOR | FACS字段 | 64位版本的唤醒向量 | FACS偏移24 |
| _WAK | 控制方法 | 唤醒后执行的AML代码 | DSDT |
| PWRBTN_STS | 寄存器位 | 电源按钮事件状态位。硬件在电源按钮按下时自动置1;OS处理完成后写1清除。 | PM1状态寄存器(PM1_STS) |
| WAK_STS | 寄存器位 | 唤醒状态位。硬件在系统从S3唤醒时自动置1;OS处理完成后写1清除。 | PM1状态寄存器(PM1_STS) |
| SLP_EN | 寄存器位 | 睡眠使能位。OS在准备进入睡眠状态时将此位置1,触发硬件执行睡眠时序。 | PM1控制寄存器(PM1_CNT) |
| SLP_TYP | 寄存器字段 | 睡眠类型字段。OS写入目标S状态对应的编码值,指定睡眠深度。 | PM1控制寄存器(PM1_CNT) |