---
title: 休眠与唤醒
url: https://doc.liz6.com/linux-kernel/14-power-management/02-suspend-and-resume
locale: zh
area: linux-kernel
tags:
- linux-kernel
- 电源管理
date: 2026-06-30
modified: 2026-07-11
description: '覆盖: 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-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 详细流程

<svg viewBox="0 0 720 330" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Suspend-to-RAM S3 挂起与唤醒流程">
  <defs><marker id="s3ah" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker></defs>
  <rect width="720" height="330" fill="#ffffff"/>
  <text x="360" y="26" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Suspend-to-RAM (S3):挂起 4 步 → S3 睡眠 → 唤醒 4 步</text>
  <text x="360" y="42" text-anchor="middle" font-size="11" fill="#64748b">echo mem &gt; /sys/power/state · kernel/power/suspend.c · pm_suspend()</text>

  <rect x="50" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="120" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">① 冻结用户进程</text>
  <text x="120" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">freeze_processes()</text>

  <rect x="210" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="280" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">② 设备挂起</text>
  <text x="280" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">dpm_suspend()</text>

  <rect x="370" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="440" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">③ 禁用非启动CPU</text>
  <text x="440" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">disable_nonboot_cpus()</text>

  <rect x="530" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="600" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">④ syscore+进S3</text>
  <text x="600" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">acpi_suspend_enter()</text>

  <line x1="190" y1="85" x2="210" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <line x1="350" y1="85" x2="370" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <line x1="510" y1="85" x2="530" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>

  <rect x="50" y="130" width="620" height="34" rx="8" fill="#e2e8f0"/>
  <text x="360" y="151" text-anchor="middle" font-size="12" font-weight="700" fill="#475569">此刻系统在 S3 中 —— RAM 自刷新,CPU/设备断电,等待唤醒源</text>

  <line x1="600" y1="114" x2="600" y2="129" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <line x1="120" y1="164" x2="120" y2="179" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <text x="130" y="175" font-size="10" fill="#64748b">唤醒触发: RTC闹钟 / Lid open / 按键</text>

  <rect x="50" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="120" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑤ CPU复位启动</text>
  <text x="120" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">→BIOS→resume path</text>

  <rect x="210" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="280" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑥ CPU+设备恢复</text>
  <text x="280" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">逆序恢复</text>

  <rect x="370" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="440" y="213" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑦ 解冻用户进程</text>

  <rect x="530" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="600" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑧ 返回用户态</text>
  <text x="600" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">echo mem 下一行继续</text>

  <line x1="190" y1="209" x2="210" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <line x1="350" y1="209" x2="370" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>
  <line x1="510" y1="209" x2="530" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#s3ah)"/>

  <rect x="50" y="256" width="620" height="58" rx="8" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="66" y="278" font-size="12.5" fill="#3730a3">全程 8 步都在内核态完成;用户进程从①冻结到⑦解冻,期间不能持有任何锁。</text>
  <text x="66" y="298" font-size="12.5" fill="#3730a3">S3 期间 RAM 自刷新、CPU/设备断电,功耗低至 ~1W;唤醒约 1–2 秒,依赖 BIOS/UEFI ACPI S3 支持。</text>
</svg>

## Hibernate (Suspend-to-Disk)

<svg viewBox="0 0 720 330" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Suspend-to-Disk 休眠写入与恢复流程">
  <defs><marker id="hibah" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker></defs>
  <rect width="720" height="330" fill="#ffffff"/>
  <text x="360" y="26" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Suspend-to-Disk (S4/Hibernate):写入磁盘 → 断电 → 冷启动读回</text>
  <text x="360" y="42" text-anchor="middle" font-size="11" fill="#64748b">echo disk &gt; /sys/power/state · kernel/power/hibernate.c · hibernate()</text>

  <rect x="50" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="120" y="90" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">① 冻结进程+设备</text>

  <rect x="210" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="280" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">② 创建内存快照</text>
  <text x="280" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">遍历物理页→写swap</text>

  <rect x="370" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="440" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">③ 写 metadata</text>
  <text x="440" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">页映射,内核状态</text>

  <rect x="530" y="56" width="140" height="58" rx="6" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="600" y="78" text-anchor="middle" font-size="12" font-weight="700" fill="#3730a3">④ 再挂起设备→关机</text>
  <text x="600" y="96" text-anchor="middle" font-size="10.5" fill="#4f46e5">power off</text>

  <line x1="190" y1="85" x2="210" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <line x1="350" y1="85" x2="370" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <line x1="510" y1="85" x2="530" y2="85" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>

  <rect x="50" y="130" width="620" height="34" rx="8" fill="#e2e8f0"/>
  <text x="360" y="151" text-anchor="middle" font-size="12" font-weight="700" fill="#475569">系统已关机(power off)—— 等待下次开机,由 resume= 内核参数触发读回</text>

  <line x1="600" y1="114" x2="600" y2="129" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <line x1="120" y1="164" x2="120" y2="179" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <text x="130" y="175" font-size="10" fill="#64748b">冷启动读盘,进入 resume path</text>

  <rect x="50" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="120" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑤ resume=/dev/sda2</text>
  <text x="120" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">kernel 参数</text>

  <rect x="210" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="280" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑥ swsusp_check()</text>
  <text x="280" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">读 signature</text>

  <rect x="370" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="440" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑦ swsusp_read()</text>
  <text x="440" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">snapshot → RAM</text>

  <rect x="530" y="180" width="140" height="58" rx="6" fill="#f0fdfa" stroke="#99f6e4"/>
  <text x="600" y="202" text-anchor="middle" font-size="12" font-weight="700" fill="#115e59">⑧ 恢复内核状态</text>
  <text x="600" y="220" text-anchor="middle" font-size="10.5" fill="#0f766e">跳转到保存执行点</text>

  <line x1="190" y1="209" x2="210" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <line x1="350" y1="209" x2="370" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>
  <line x1="510" y1="209" x2="530" y2="209" stroke="#475569" stroke-width="1.6" marker-end="url(#hibah)"/>

  <rect x="50" y="256" width="620" height="58" rx="8" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="66" y="278" font-size="12.5" fill="#3730a3">全部 RAM 内容写入 swap 后整机断电,功耗降到 0W;仅写使用中的页,跳过空闲和 page cache。</text>
  <text x="66" y="298" font-size="12.5" fill="#3730a3">下次开机靠 resume= 内核参数触发读回,唤醒约 10–30 秒,取决于 RAM 大小和磁盘速度。</text>
</svg>

## Runtime PM: 设备级电源管理

```c
// 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 设备)
```

## 调试

```bash
# 支持的休眠状态
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*
