ACPI电源按钮唤醒S3切换到S0流程(附流程图)

ACPI电源按钮唤醒S3切换到S0流程(附流程图)

本文属于《 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停止执行,内存自刷新,但芯片组的唤醒逻辑和部分待机电源仍在工作。

  1. 用户按下电源按钮:产生物理信号。
  2. EC捕获并转发 :嵌入式控制器检测到按钮按下,向芯片组的PWRBTN#专用引脚发送一个低脉冲。
  3. 芯片组唤醒逻辑启动
    • 芯片组检测到PWRBTN#信号。
    • 寄存器操作: 芯片组硬件将PM1状态寄存器 中的 PWRBTN_STS(电源按钮状态)位 置为 1,记录唤醒事件源。
    • 寄存器操作: 芯片组硬件将PM1状态寄存器 中的 WAK_STS(唤醒状态)位 置为 1,表示系统从睡眠状态唤醒。
  4. 硬件恢复电源
    • 芯片组解除SLP_S3#信号的断言(assertion),主电源轨恢复供电。
    • CPU接收POWER GOOD信号,从重置向量开始执行。

第二阶段:固件早期恢复(BIOS/UEFI)

此时CPU开始在实模式下执行固件代码。

  1. BIOS早期初始化 :快速初始化内存控制器、芯片组等必要部分,但不破坏内存中的内容
  2. 检测唤醒源(固件视角)
    • BIOS读取PM1状态寄存器,发现 WAK_STS1,确认是从S3唤醒,而非冷启动。
    • (可选)BIOS可以读取PWRBTN_STS位,确认具体的唤醒原因。
  3. 查找OS唤醒向量
    • BIOS读取FACS 表中的FIRMWARE_WAKING_VECTOR,这个地址是操作系统在休眠前写入的,指向OS唤醒代码的入口。
  4. 跳转到OS:BIOS执行远跳转,进入OS的实模式唤醒代码。

第三阶段:OS内核重入(恢复执行上下文)

此时CPU进入OS的实模式唤醒代码,准备恢复执行。

  1. OS唤醒代码开始执行 :入口点通常是wakeup.S,CPU处于实模式。
  2. 恢复CPU运行环境
    • 代码通过ljmpl指令切换回保护模式。
    • 恢复休眠前保存的GDT、IDT和寄存器状态。
  3. 从休眠函数返回
    • 当CPU状态完全恢复后,代码从do_suspend_lowlevel()返回,看起来就像是从acpi_enter_sleep_state()函数正常返回一样。
    • 重新获取内核锁,恢复中断处理。

第四阶段:AML执行与设备恢复

此时内核已恢复基本运行,开始与ACPI固件交互并恢复设备。

  1. 调用_WAK方法
    • 内核调用ACPI控制方法_WAK,将唤醒状态作为参数传入。
    • _WAK方法由BIOS提供,执行平台特定的唤醒后操作(如重新配置EC、恢复某些GPIO状态)。
  2. OS确定唤醒源(OSPM视角)
    • 寄存器操作: OS读取PM1状态寄存器,发现 PWRBTN_STS1,确认是电源按钮唤醒了系统。
    • 寄存器操作: OS软件向PM1状态寄存器PWRBTN_STS位写入1,清除该状态位,表示事件已处理。
    • 寄存器操作: OS软件向PM1状态寄存器WAK_STS位写入1,清除唤醒状态标志。
  3. 恢复设备驱动
    • 内核遍历设备树,为每个设备调用注册的resume回调函数。
    • 设备驱动恢复硬件状态,重新初始化寄存器。
  4. 恢复控制台和中断:重新启用控制台输出,恢复所有中断。

第五阶段:软件恢复完成

  1. 解冻用户空间:内核解冻之前冻结的用户进程和内核线程。
  2. 返回用户空间:系统完全恢复到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)
相关推荐
百里杨7 小时前
ACPI休眠按钮触发S0切换到S3流程(附流程图)
s3·acpi·s0
sitelist2 个月前
ACPI!device后ACPI!Name函数建立子节点对象
device·name·acpi
亚林瓜子3 个月前
AWS中国云中的ETL之从aurora搬数据到s3(Glue版——修复版)
云计算·etl·aws·s3·glue
nicepainkiller3 个月前
aws s3 对象存储 上传文件
云计算·aws·s3
DevOps0088 个月前
将 RustFS 用作 GitLab 对象存储后端
rust·gitlab·minio·分布式存储·s3·rustfs
ApacheSeaTunnel8 个月前
MySQL 数据同步至 S3file,并接入 Hive 访问:SeaTunnel 实践指南
大数据·mysql·开源·数据集成·s3·seatunnel·数据同步
DevOps0088 个月前
在 Azure Linux 上安装 RustFS
rust·minio·分布式存储·s3·rustfs
亚林瓜子9 个月前
AWS S3拒绝非https的请求访问
https·云计算·json·ssl·aws·s3
为美好的生活献上中指10 个月前
java每日精进 5.18【文件存储】
java·开发语言·minio·七牛云存储·s3·七牛云