# 14.6.电源和资源管理

## 14.6.1. ACPI 配置

在 FreeBSD 中，资源管理由 [acpi(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi\&sektion=4\&format=html) 内核设备管理。

> **注意**
>
> 在 FreeBSD 中，[acpi(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi\&sektion=4\&format=html) 驱动程序在系统启动时默认加载。
>
> 此驱动程序 **无法在启动后卸载**，因为系统总线依赖它进行各种硬件交互。

除了 [acpi(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi\&sektion=4\&format=html)，FreeBSD 还有多个针对不同 ACPI 厂商子系统的专用内核模块。这些模块会添加一些额外功能，例如风扇速度、键盘背光或屏幕亮度等。

可以通过执行以下命令来获取模块列表：

```sh
% ls /boot/kernel | grep acpi
```

输出应类似于以下内容：

```sh
acpi_asus.ko
acpi_asus_wmi.ko
acpi_dock.ko
acpi_fujitsu.ko
acpi_hp.ko
acpi_ibm.ko
acpi_panasonic.ko
acpi_sony.ko
acpi_toshiba.ko
acpi_video.ko
acpi_wmi.ko
sdhci_acpi.ko
uacpi.ko
```

例如，如果使用 IBM/Lenovo 笔记本电脑，则需要加载 [acpi\_ibm(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi_ibm\&sektion=4\&format=html) 模块，可以通过以下命令加载：

```sh
# kldload acpi_ibm
```

并在 **/boot/loader.conf** 中添加以下行，以便在启动时自动加载该模块：

```sh
acpi_ibm_load="YES"
```

[acpi\_video(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi_video\&sektion=4\&format=html) 模块的替代方案是 [backlight(9)](https://man.freebsd.org/cgi/man.cgi?query=backlight\&sektion=9\&format=html) 驱动程序。它提供了一种通用方式来处理面板背光。默认的 GENERIC 内核包括此驱动程序。可以使用 [backlight(8)](https://man.freebsd.org/cgi/man.cgi?query=backlight\&sektion=8\&format=html) 工具查询并调整面板背光亮度。在此示例中，亮度降低了 10%：

```sh
% backlight decr 10
```

## 14.6.2. CPU 电源管理

CPU 是系统中最耗能的部分。了解如何提高 CPU 效率是节能的基本部分。

为了正确地利用机器的资源，FreeBSD 支持 Intel Turbo Boost、AMD Turbo Core、Intel Speed Shift 等技术，通过使用 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 和 [cpufreq(4)](https://man.freebsd.org/cgi/man.cgi?query=cpufreq\&sektion=4\&format=html)。

第一步是通过以下命令获取 CPU 信息：

```sh
% sysctl dev.cpu.0 ①
```

* ① 此处的 `0` 表示 CPU 的第一个核心。

输出应类似于以下内容：

```sh
dev.cpu.0.cx_method: C1/mwait/hwc C2/mwait/hwc C3/mwait/hwc/bma
dev.cpu.0.cx_usage_counters: 3507294 0 0
dev.cpu.0.cx_usage: 100.00% 0.00% 0.00% last 3804us
dev.cpu.0.cx_lowest: C3 ①
dev.cpu.0.cx_supported: C1/1/1 C2/2/1 C3/3/57 ②
dev.cpu.0.freq_levels: 2267/35000 2266/35000 1600/15000 800/12000 ③
dev.cpu.0.freq: 1600 ④
dev.cpu.0.temperature: 40.0C ⑤
dev.cpu.0.coretemp.throttle_log: 0
dev.cpu.0.coretemp.tjmax: 105.0C
dev.cpu.0.coretemp.resolution: 1
dev.cpu.0.coretemp.delta: 65
dev.cpu.0.%parent: acpi0
dev.cpu.0.%pnpinfo: _HID=none _UID=0 _CID=none
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%driver: cpu
dev.cpu.0.%desc: ACPI CPU
```

* ① 最低 Cx 状态，用于空闲时使 CPU 进入该状态。
* ② 支持的 CPU Cx 状态。
* ③ 当前可用的 CPU 频率级别（频率/功耗）。
* ④ 当前活动的 CPU 频率（单位：MHz）。
* ⑤ 当前 CPU 的温度。

> **注意**
>
> 如果未显示温度信息，请加载 [coretemp(4)](https://man.freebsd.org/cgi/man.cgi?query=coretemp\&sektion=4\&format=html) 模块。使用 AMD CPU 时，请加载 [amdtemp(4)](https://man.freebsd.org/cgi/man.cgi?query=amdtemp\&sektion=4\&format=html) 模块。

获取到 CPU 信息后，配置省电的最简便方法是让 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 接管。

在 **/etc/rc.conf** 中启用 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 服务，以便在系统启动时自动启动：

```sh
# sysrc powerd_enable=YES
```

还需要为 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 提供一些参数，告诉它如何管理 CPU 状态，可以执行以下命令：

```sh
# sysrc powerd_flags="-a hiadaptive -i 25 -r 85 -N"
```

1. `-a`：选择 AC 电源下的操作模式。
2. `hiadaptive`：操作模式。更多信息请参见 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html)。
3. `-i`：指定当自适应模式开始降低性能以节省电力时的 CPU 负载百分比。
4. `-r`：指定当自适应模式认为 CPU 正在运行并提高性能时的 CPU 负载百分比。
5. `-N`：将“nice”时间视为空闲时间以进行负载计算；即仅当 CPU 正忙于“nice”进程时，不会提高 CPU 频率。

然后启用该服务，执行以下命令：

```sh
# service powerd start
```

## 14.6.3. CPU 频率控制

FreeBSD 包含一款通用的 [cpufreq(4)](https://man.freebsd.org/cgi/man.cgi?query=cpufreq\&sektion=4\&format=html) 驱动程序，能让管理员或诸如 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 和 [sysutils/powerdxx](https://cgit.freebsd.org/ports/tree/sysutils/powerdxx/) 等软件来管理 CPU 的频率，以实现性能与经济之间的平衡。较低的设置可以节省电力并减少 CPU 产生的热量，而较高的设置则会提高性能，但会增加电力消耗并产生更多热量。

## 14.6.4. Intel® Enhanced Speed Step™

Intel® Enhanced Speed Step™ 驱动程序 [est(4)](https://man.freebsd.org/cgi/man.cgi?query=est\&sektion=4\&format=html) 会替代通用的 [cpufreq(4)](https://man.freebsd.org/cgi/man.cgi?query=cpufreq\&sektion=4\&format=html) 驱动程序，用于支持此功能的 CPU。可以使用 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html) 静态调整 CPU 频率，或使用 `/etc/rc.d/power_profile` 启动脚本。额外的软件，如 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 或 [sysutils/powerdxx](https://cgit.freebsd.org/ports/tree/sysutils/powerdxx/)，可以根据处理器的利用率自动调整 CPU 频率。

可以通过查看 [sysctl(3)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=3\&format=html) 树列出每个支持的频率及其预期的功耗：

```sh
# sysctl dev.cpufreq.0.freq_driver dev.cpu.0.freq_levels dev.cpu.0.freq
```

输出应类似于以下内容：

```sh
dev.cpufreq.0.freq_driver: est0
dev.cpu.0.freq_levels: 3001/53000 3000/53000 2900/50301 2700/46082 2600/43525 2400/39557 2300/37137 2100/33398 2000/31112 1800/27610 1700/25455 1500/22171 1400/20144 1200/17084 1100/15181 900/12329 800/10550
dev.cpu.0.freq: 800
```

频率比 CPU 最大频率高 1 MHz 表示启用了 Intel® Turbo Boost™ 功能。

## 14.6.5. Intel Speed Shift™

对于运行较新 Intel® CPU 的用户，在升级到 FreeBSD 13 后，可能会发现动态频率控制有所不同。对于某些 SKU，FreeBSD 13 引入了 [hwpstate\_intel(4)](https://man.freebsd.org/cgi/man.cgi?query=hwpstate_intel\&sektion=4\&format=html) 驱动程序，它使硬件能够动态地调整核心频率，包括按核心调整。FreeBSD 13 使用该驱动程序自动启用 Speed Shift™ 控制，替代了旧的 Enhanced Speed Step™ [est(4)](https://man.freebsd.org/cgi/man.cgi?query=est\&sektion=4\&format=html) 驱动程序。可以通过查看 `dev.cpufreq.%d.freq_driver` 来确定系统正在使用哪种频率控制驱动程序。

要确定正在使用的频率控制驱动程序，可以检查 `dev.cpufreq.0.freq_driver` oid：

```sh
# sysctl dev.cpufreq.0.freq_driver
```

输出应类似于以下内容：

```sh
dev.cpufreq.0.freq_driver: hwpstate_intel0
```

这表示正在使用新的 [hwpstate\_intel(4)](https://man.freebsd.org/cgi/man.cgi?query=hwpstate_intel\&sektion=4\&format=html) 驱动程序。在此类系统上，oid `dev.cpu.%d.freq_levels` 将只显示 CPU 的最大频率，并且将显示功耗级别为 `-1`。

可以通过检查 `dev.cpu.%d.freq` oid 来确定当前 CPU 频率：

```sh
# sysctl dev.cpu.0.freq_levels dev.cpu.0.freq
```

输出应类似于以下内容：

```sh
dev.cpu.0.freq_levels: 3696/-1
dev.cpu.0.freq: 898
```

有关更多信息，包括如何平衡性能和能耗，以及如何禁用此驱动程序，请参考 man 页面 [hwpstate\_intel(4)](https://man.freebsd.org/cgi/man.cgi?query=hwpstate_intel\&sektion=4\&format=html)。

> **注意**
>
> 习惯使用 [powerd(8)](https://man.freebsd.org/cgi/man.cgi?query=powerd\&sektion=8\&format=html) 或 [sysutils/powerdxx](https://cgit.freebsd.org/ports/tree/sysutils/powerdxx/) 的用户会发现这些工具已被 [hwpstate\_intel(4)](https://man.freebsd.org/cgi/man.cgi?query=hwpstate_intel\&sektion=4\&format=html) 驱动程序所取代，不再按预期工作。

## 14.6.6. 显卡电源管理

近年来，显卡已成为计算机的基本组成部分。一些显卡可能会有过高的功耗，FreeBSD 允许通过特定的配置来改善功耗。

如果使用的是带有 [graphics/drm-kmod](https://cgit.freebsd.org/ports/tree/graphics/drm-kmod/) 驱动程序的 Intel® 显卡，可以将以下选项添加到 **/boot/loader.conf** 中：

```ini
compat.linuxkpi.fastboot=1  ①
compat.linuxkpi.enable_dc=2 ②
compat.linuxkpi.enable_fbc=1③
```

* ① 尝试跳过启动时不必要的模式设置。
* ② 启用省电显示 C 状态。
* ③ 启用帧缓冲压缩以节省电力。

## 14.6.7. 挂起/恢复

挂起/恢复功能允许计算机保持在一个低功耗状态，并且可以在不丢失正在运行的程序状态的情况下恢复系统。

> **注意**
>
> 为了使挂起/恢复功能正常工作，系统必须加载图形驱动程序。在不支持 KMS 的显卡上，必须使用 [sc(4)](https://man.freebsd.org/cgi/man.cgi?query=sc\&sektion=4\&format=html) 驱动程序，以避免破坏挂起/恢复功能。
>
> 更多有关使用哪些驱动程序以及如何配置的信息，参见 [The X Window System chapter](https://docs.freebsd.org/en/books/handbook/x11/#x11) 。

[acpi(4)](https://man.freebsd.org/cgi/man.cgi?query=acpi\&sektion=4\&format=html) 支持以下睡眠状态：

| 表 4. 支持的睡眠状态 | 描述                                                      |
| ------------ | ------------------------------------------------------- |
| S1           | 快速挂起到 RAM。CPU 进入较低的功耗状态，但大多数外围设备保持运行。                   |
| S2           | 比 S1 更低的功耗状态，但具有相同的基本特征。许多系统不支持此状态。                     |
| S3（睡眠模式）     | 挂起到 RAM。大多数设备断电，系统停止运行，仅内存保持刷新。                         |
| S4（休眠）       | 挂起到磁盘。所有设备断电，系统停止运行。恢复时，系统从冷启动状态开始。**FreeBSD 尚不支持此功能**。 |
| S5           | 系统干净地关机并断电。                                             |

### 14.6.7.1. 配置挂起/恢复

第一步是通过执行以下命令来了解硬件支持哪种类型的睡眠状态：

```sh
% sysctl hw.acpi.supported_sleep_state
```

输出应类似于以下内容：

```sh
hw.acpi.supported_sleep_state: S3 S4 S5
```

> **警告**
>
> 如上所述，FreeBSD **尚不** 支持 `S4` 状态。

可以使用 [acpiconf(8)](https://man.freebsd.org/cgi/man.cgi?query=acpiconf\&sektion=8\&format=html) 来检查 `S3` 状态是否正常工作，执行以下命令，如果成功，屏幕将变黑，机器将关闭：

```sh
# acpiconf -s 3
```

在绝大多数情况下，挂起/恢复功能用于笔记本电脑。

可以通过在 **/etc/sysctl.conf** 文件中添加以下行来配置 FreeBSD 在关闭笔记本盖子时进入 `S3` 状态：

```ini
hw.acpi.lid_switch_state=S3
```

### 14.6.7.2. 挂起/恢复故障排除

FreeBSD 在使挂起和恢复功能正常工作并达到最佳效果方面做了很多努力。然而，目前挂起和恢复功能仅在一些特定的笔记本电脑上能够正常工作。

如果挂起/恢复功能无法正常工作，可以进行一些检查。

在某些情况下，仅关闭蓝牙即可解决问题。在其他情况下，加载正确的显卡驱动程序等措施也可能解决问题。

如果问题仍然存在，可以在 FreeBSD Wiki 的 [Suspend/Resume](https://wiki.freebsd.org/SuspendResume) 部分找到一些故障排除的提示。
