前段时间因为意外重装了一下系统,由于 S4 休眠需要额外的配置,大部分发行版默认是不提供的,正好就这次重新配置记录一下。

前期准备

注意
这部分内容在实际配置的过程中并没有执行,而是直接基于旧系统的遗留,复制命令时请注意甄别,如发现有误欢迎通知作者修改。

S4 休眠是深度最高的一种休眠,会将内存数据写入硬盘并关闭电源,因此休眠过程中不会产生电量消耗。最重要的是,由于操作系统交出了所有硬件的控制权限,在休眠过程中是可以切换系统的,作为双系统玩家,基本是我日常必用的工具。

不同于 Windows 下严格区分休眠文件和交换文件(由于历史原因命名和 Linux 下存在一定差异,分别对应 hiberfil.syspagefile.sys),Linux 统一使用交换空间(swap space),且支持独立的交换分区。S4 休眠需要足够的交换空间,一般建议大于物理内存,对于小于物理内存的情况未进行过测试。

❯ free -h
                总计        已用        空闲        共享      缓冲/缓存        可用
内存:          38Gi       5.9Gi        27Gi       1.0Gi       6.2Gi        32Gi
交换:          64Gi          0B        64Gi
❯ swapon --show
NAME           TYPE      SIZE USED PRIO
/dev/nvme0n1p5 partition  64G   0B   -1

因为上次根文件系统炸掉的时候没有影响到交换分区就直接用了,一般情况下需要重新创建或调整大小,以下两种任选其一即可。

创建交换分区

首先使用分区工具创建新分区,以我目前环境为例为 /dev/nvme0n1p5,然后对其进行格式化,然后挂载:

sudo mkswap /dev/nvme0n1p5
sudo swapon /dev/nvme0n1p5
注意
大部分博客习惯使用 /dev/sd* 作为硬盘设备文件,除更简短外也存在一部分历史因素,然而现代计算机中 /dev/sd* 多为 SATA 设备,而 NVMe 设备则为 /dev/nvme*,交换空间建议置于 SSD 中。

创建交换文件

原则上交换文件可以置于任何位置,但一般直接放在根目录下,其本身作为环回设备,对文件名没有特殊要求,这里以 /swap.img 为例,注意按照实际需要调整大小。

sudo fallocate -l 64G /swap.img
sudo mkswap /swap.img
sudo swapon /swap.img

交换分区挂载建议写入 /etc/fstab,Archlinux 下也直接使用 genfstab 生成。

修改 grub 配置

这一步主要是为了告诉内核在启动时尝试从休眠景象中恢复,在 /etc/default/grub 中添加以下参数(以交换分区为例):

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=xxxx"

xxxx 更换为交换分区的 UUID, 可以使用 blkid 命令查看。

对于交换文件,需要额外指定文件在分区中的偏移量:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=xxxx resume_offset=xxxx"

交换文件在分区中的偏移量可以通过 filefrag -v 命令查看:

❯ filefrag -v temp                         
Filesystem type is: 9123683e
File size of temp is 1048576 (256 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..     255:    4886416..   4886671:    256:             last,unwritten,eof
temp: 1 extent found

physical_offset 的两个值分别对应起始块和结束块的位置,启动参数中使用起始块的偏移量。

之后重新生成 grub 配置:

sudo grub-mkconfig -o /boot/grub/grub.cfg

进行休眠并重新唤醒确认是否生效:

sudo systemctl hibernate

唤醒正常按开机键就好了()

后续配置

如果不出意外的话,KDE、GNOME 等环境到这里已经可以正常使用了,不过我用的 Hyprland 下还有一点小问题,唤醒后会直接进入已登陆的会话,需要对 Hypridle 及 Hyprlock 进行配置。

~/.config/hypr/hyprland.conf 中添加以下内容:

exec-once = hypridle
bind = $mainMod, H, exec, sudo systemctl hibernate

Hypridle 的配置文件如下:

# ~/.config/hypr/hypridle.conf
general {
    lock_cmd = pidof hyprlock || hyprlock
    before_sleep_cmd = loginctl lock-session
}

Hyprlock 配置直接使用 官方示例

2026.04.12 更新

前几天配开发环境的时候发现 N 卡驱动没有装,就给补了一下,结果今天唤醒的时候发现失败了,原因是 sddm 需要 nvidia 模块早期加载,但这会导致 resume 失败。折腾半天也没找到之前是怎么配的,然后我意识到一个问题,sddm 需求 nvidia 模块是因为用 N 卡渲染,但我又不在 Arch 上打游戏,能跑 CUDA 就行,渲染交给核显不就好。

配置参数很简单,在 /etc/modprobe.d 下创建相关配置文件:

# /etc/modprobe.d/nvidia.conf
options nvidia_drm modeset=0

确认一下显示器输出:

❯ lspci -vnn | grep VGA
0000:00:02.0 VGA compatible controller [0300]: Intel Corporation Meteor Lake-P [Intel Arc Graphics] [8086:7d55] (rev 08) (prog-if 00 [VGA controller])
0000:01:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD107M [GeForce RTX 4060 Max-Q / Mobile] [10de:28a0] (rev a1) (prog-if 00 [VGA controller])

❯ la /sys/class/drm/card*
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card0 -> ../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card0
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card1-DP-1 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-1
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card1-DP-2 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-2
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card1-DP-3 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-3
lrwxrwxrwx 1 root root 0  4月12日 21:31 /sys/class/drm/card1-DP-4 -> ../../devices/pci0000:00/0000:00:02.0/drm/card1/card1-DP-4

所有显示器输出都指向 Intel 核显,与预期一致。

最后确认一下 CUDA 是否正常工作(更多是看 pytorch 是否正常):

❯ python -c "import torch; print(f'{torch.cuda.is_available()=}')"
torch.cuda.is_available()=True