本页目录

休眠与唤醒

覆盖: suspend-to-RAM (S3) → suspend-to-disk (S4/hibernate) → freeze (suspend-to-idle) → runtime PM → ACPI S-states → 驱动 PM 回调 → 调试 内核版本: 2.6 ~ 6.x

系统休眠状态

suspend-to-idle (freeze / s2idle):
  冻结用户进程 + 设备进入低功耗 + CPU idle
  → 功耗: 中等, 唤醒: 最快 (~100ms)
  → 依赖: 所有设备和 CPU 有好的 runtime PM 支持

suspend-to-RAM (S3 / deep):
  RAM 自刷新, CPU 和大部分设备断电
  → 功耗: 低 (~1W), 唤醒: ~1-2 秒
  → BIOS/UEFI ACPI S3 支持

suspend-to-disk (S4 / hibernate):
  全部 RAM 内容写 swap 或文件, 全机断电
  → 功耗: 0W, 唤醒: ~10-30 秒 (取决于 RAM 大小和磁盘速度)
  → 内核 resume: 读 swap image 回 RAM → 恢复执行

Suspend-to-RAM 详细流程

Suspend-to-RAM (S3):挂起 4 步 → S3 睡眠 → 唤醒 4 步 echo mem > /sys/power/state · kernel/power/suspend.c · pm_suspend() ① 冻结用户进程 freeze_processes() ② 设备挂起 dpm_suspend() ③ 禁用非启动CPU disable_nonboot_cpus() ④ syscore+进S3 acpi_suspend_enter() 此刻系统在 S3 中 —— RAM 自刷新,CPU/设备断电,等待唤醒源 唤醒触发: RTC闹钟 / Lid open / 按键 ⑤ CPU复位启动 →BIOS→resume path ⑥ CPU+设备恢复 逆序恢复 ⑦ 解冻用户进程 ⑧ 返回用户态 echo mem 下一行继续 全程 8 步都在内核态完成;用户进程从①冻结到⑦解冻,期间不能持有任何锁。 S3 期间 RAM 自刷新、CPU/设备断电,功耗低至 ~1W;唤醒约 1–2 秒,依赖 BIOS/UEFI ACPI S3 支持。

Hibernate (Suspend-to-Disk)

Suspend-to-Disk (S4/Hibernate):写入磁盘 → 断电 → 冷启动读回 echo disk > /sys/power/state · kernel/power/hibernate.c · hibernate() ① 冻结进程+设备 ② 创建内存快照 遍历物理页→写swap ③ 写 metadata 页映射,内核状态 ④ 再挂起设备→关机 power off 系统已关机(power off)—— 等待下次开机,由 resume= 内核参数触发读回 冷启动读盘,进入 resume path ⑤ resume=/dev/sda2 kernel 参数 ⑥ swsusp_check() 读 signature ⑦ swsusp_read() snapshot → RAM ⑧ 恢复内核状态 跳转到保存执行点 全部 RAM 内容写入 swap 后整机断电,功耗降到 0W;仅写使用中的页,跳过空闲和 page cache。 下次开机靠 resume= 内核参数触发读回,唤醒约 10–30 秒,取决于 RAM 大小和磁盘速度。

Runtime PM: 设备级电源管理

// drivers/base/power/runtime.c
// 每个设备可以独立挂起/恢复 (不影响其他设备和进程)

// 自动挂起条件:
//   - 设备 idle 超过 autosuspend_delay_ms
//   - 无引用 (pm_runtime_get/put)
//   - 驱动支持 runtime_suspend/runtime_resume

// PCIe: runtime D3hot (断电但保持 PCIe link)
// USB:  selective suspend (挂起单个 USB 设备)

调试

# 支持的休眠状态
cat /sys/power/state          # freeze mem disk

# 挂起/唤醒追踪
echo 1 > /sys/power/pm_trace  # 通过 RTC hash 追踪故障设备
dmesg | grep -i "PM: suspend" # 挂起/唤醒日志

# 哪个设备阻止了挂起
cat /sys/power/pm_wakeup_irq  # 最后一个唤醒 IRQ
dmesg | grep -i "wakeup"      # 唤醒源

# 分析挂起/唤醒延迟
echo 1 > /sys/kernel/debug/tracing/events/power/suspend_resume/enable
cat trace_pipe

参考

  • 源码⁠: kernel/power/suspend.c, kernel/power/hibernate.c, drivers/base/power/, drivers/acpi/sleep.c
  • 内核文档⁠: Documentation/admin-guide/pm/sleep-states.rst, Documentation/power/runtime_pm.rst

关键词: suspend, hibernate, freeze, s2idle, S3, S4, runtime PM, pm_wakeup, ACPI