Gentoo Logo

电源管理指导

内容:

1.  介绍

最近的几年中,笔记本电脑电池的容量和寿命都有了很大的提高。然而现代的处理器比旧的更加耗能而每一代新的笔记本电脑又增加了许多蚕食电源的设备。正因为如此,电源管理比以前任何时候都重要。增加电池的使用时间并不意味着你需要多买一个电池。很大程度可以通过使用智能的电源管理策略来实现。

概述

请注意,这篇指导描述的是笔记本电脑的电源管理。虽然其中有些小节也可适用于服务器,但其它的部分则不适用并可能造成损害。所以请不要把本指导应用于服务器,除非你确实知道你在干什么。

因为这篇指导的确比较长,这个短短的概述帮你统领全篇。

前提条件一章讲了使接下来的设备部分能有效实现的一些前提条件。其中包括了BIOS的设定、内核的编译以及用户方面的简化设定。接下来的三章聚焦于典型的耗电设备: 处理器、显示器和硬盘。它们都可以被单独配置。CPU 电源管理展示了如何通过调整处理器的主频来尽可能地节省电源,同时不损失太多的性能。在硬盘电源管理中有一些不同的、避免你硬盘不必要地工作的小技巧(附带地,也使硬盘的工作噪声降低)。关于显卡、无线网卡及USB的注意事项请见其它设备的电源管理,而其它章节则致力于(非常试验性的)休眠状态。最后常见问题中列出了一些易犯的错误。

每部分的电源预算


图示 1.1: 每部分的电量预算

Fig. 1: 每部分消耗了多少电量?

几乎每部分都可以在不同的状态下工作——关闭、休眠、空闲、激活,即消耗不同的电量。电量主要消耗于LCD显示器、CPU、芯片组和硬盘。通常情况下,我们可以在BIOS中激活操作系统无关的电源管理,但是在操作系统中的智能设置则可以适应于不同的情况,从而实现更多。

2.  前提条件

在讨论如何使单独的设备能实现电源管理之前,先确定已经具备了一些必要的条件。在设置好BIOS后,一些内核的选项需要选上——简单地说就是ACPI、休眠状态(sleep states)和CPU降频(CPU frequency scaling)。因为在大多数情况下,节能就意味着性能的损失或是响应速度的下降,所以应该仅在使用电池时启用。使用一个新的运行级别battery,意为电池,将会很方便。

BIOS部分

首先,我们来看看和电源管理有关的BIOS设定。最好的方式是将BIOS的设置和操作系统的策略结合起来,不过现在最好把绝大部分BIOS相关的部分禁用掉。以确保它不会干扰你的策略。不要忘了在你完成了其他设置后再检查一下你的BIOS设置。

设定USE标记

请检查一下acpi的USE标记已经在/etc/make.conf中设置了。其他你可能感兴趣的USE标记是apmlm-sensorsnforce2nvidiapmu。查阅/usr/portage/profiles/use*.desc来获得更多的细节。如果你忘了设置这些标记,你可以用--newuse参数重新emerge那些受影响的包。

配置内核

ACPI(高级配置与电源接口)的内核支持依然在开发中。使用最新的内核确保你可以最大程度地利用它。

Portage中有多个不同的内核。我推荐使用gentoo-sources或者tuxonice-sources。后者包括了TuxOnIce的补丁,参见有关休眠状态的章节。当配置内核的时候,至少应启用下面这些选项:

代码 2.1: 电源管理的内核最简设置(内核2.6)

Power management and ACPI options --->
  [*] Power Management support
  [ ] Software Suspend

  ACPI( Advanced Configuration and Power Interface ) Support --->
    [ ]   Deprecated /proc/acpi/files
    [*]   AC Adapter
    [*]   Battery
    <M>   Button
    <M>   Video
    [ ]   Generic Hotkey
    <M>   Fan
    <M>   Processor
    <M>     Thermal Zone
    < >   ASUS/Medion Laptop Extras
    < >   IBM ThinkPad Laptop Extras
    < >   Toshiba Laptop Extras
    (0)   Disable ACPI for systems before Jan 1st this year
    [ ]   Debug Statements
    [*]   Power Management Timer Support
    < >   ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)

  CPU Frequency Scaling --->
    [*] CPU Frequency scaling
    [ ]   Enable CPUfreq debugging
    < >   CPU frequency translation statistics
    [ ]     CPU frequency translation statistics details
          Default CPUFreq governor (userspace)
    <*>   'performance' governor
    <*>   'powersave' governor
    <*>   'ondemand' cpufreq policy governor
    <*>   'conservative' cpufreq governor
    <*>   CPU frequency table helpers
    <M> ACPI Processor P-States driver
    <*> CPUFreq driver for your processor

自己决定你是否需要休眠(Software Suspend)、挂起状态(Sleep States)(见正文)。如果你用的是ASUS、Median、IBM ThinkPad或者Toshiba的笔记本,就选择相应的部分。

内核需要知道如何为你处理器启动CPU降频。因为每种CPU都有不同的接口,所以你得为你的处理器选择正确的驱动。要小心的是——比如,在Pentim M的系统上启用Intel Pentium 4 clock modulation会导致奇怪的结果。如果你不能确定选择哪一个,查阅一下内核的文档。

编译你的内核,确保开机时加载了正确的模块并启动进入你新的启用了ACPI的内核。接着运行emerge sys-power/acpid以获得acpi的后台程序。它会通知你相关的事件,如从AC电源切换到电池或者合上了笔记本。如果你没有把相应的模块编译进内核的话,一定要确保已经加载了它们。然后通过执行 /etc/init.d/acpid start来启动acpid。很快你就会看到如何使用它。

代码 2.2: 安装acpid

# emerge sys-power/acpid
# /etc/init.d/acpid start
# rc-update add acpid default

创建"battery"运行级别

默认的策略是当且仅当需要的时候启动电源管理——使用电池的时候。为了能方便地在AC电源和电池的状态间切换,创建一个运行级别battery来控制启动和关闭电源管理的脚本。

注意: 如果你不喜欢使用另一个运行级别的办法,你可以安全地跳过这部分。不过,跳过这一步就需要一些技巧来设置了。下面的都是假设有一个battery的运行级别存在的。

代码 2.3: 创建battery运行级别

# cd /etc/runlevels
# cp -a default battery

完成了。你新的运行级别battery包含了所有default级别中的东西,但是还没有它们之间的自动切换,让我们改变一下吧。

响应ACPI事件

典型的ACPI事件有合上笔记本、电源切换及按下休眠键等。其中一个重要的事件是切换电源,此时应该导致一次运行级别的切换。一个小脚本会处理它。

首先,你需要一个脚本根据电源情况在defaultbattery间切换。这个脚本使用sys-power/pm-utils中的on_ac_power命令——所以确定这个包已经安装在你的系统上了。

代码 2.4: 安装pm-utils

# emerge pm-utils

现在你可以通过在shell中执行on_ac_power && echo AC available || echo Running on batteries来知道电源的状况。下面这个脚本是用来改变运行级别的。将它保存为/etc/acpi/actions/pmg_switch_runlevel.sh

代码 2.5: /etc/acpi/actions/pmg_switch_runlevel.sh

#!/bin/bash

# BEGIN configuration
RUNLEVEL_AC="default"
RUNLEVEL_BATTERY="battery"
# END configuration


if [ ! -d "/etc/runlevels/${RUNLEVEL_AC}" ]
then
    logger "${0}: Runlevel ${RUNLEVEL_AC} does not exist. Aborting."
    exit 1
fi

if [ ! -d "/etc/runlevels/${RUNLEVEL_BATTERY}" ]
then
    logger "${0}: Runlevel ${RUNLEVEL_BATTERY} does not exist. Aborting."
    exit 1
fi

if on_ac_power
then
    if [[ "$(</var/lib/init.d/softlevel)" != "${RUNLEVEL_AC}" ]]
    then
        logger "Switching to ${RUNLEVEL_AC} runlevel"
         /sbin/rc ${RUNLEVEL_AC}
    fi
elif [[ "$(</var/lib/init.d/softlevel)" != "${RUNLEVEL_BATTERY}" ]]
then
    logger "Switching to ${RUNLEVEL_BATTERY} runlevel"
    /sbin/rc ${RUNLEVEL_BATTERY}
fi

不要忘了chmod +x /etc/acpi/actions/pmg_switch_runlevel.sh使脚本可以执行。最后一件事是在电源切换的时候运行这个脚本。这是通过acpid获取ACPI事件实现的。在大多数笔记本上,这些事件叫做ac_adapterbattery,不过在你的机子上可能是不同的。

代码 2.6: 确定切换电源的ACPI事件

# tail -f /var/log/messages | grep "ACPI event"

执行上面的命令并拔下电源线,你看见像下面的输出:

代码 2.7: 电源切换输出例子

[Tue Sep 20 17:39:06 2005] ACPI event "ac_adapter AC 00000080 00000000"
[Tue Sep 20 17:39:06 2005] ACPI event "battery BAT0 00000080 00000001"

我们感兴趣的部分是ACPI event后面的引号部分。它会匹配我们下面要创建的文件中有关事件的行。如果你的系统产生了多个事件或相同的事件,不用担心。只要产生了任何事件,运行级别的改变就会工作。

代码 2.8: /etc/acpi/events/pmg_ac_adapter

# replace "ac_adapter" below with the event generated on your laptop
# For example, ac_adapter.* will match ac_adapter AC 00000080 00000000
event=ac_adapter.*
action=/etc/acpi/actions/pmg_switch_runlevel.sh %e

代码 2.9: /etc/acpi/events/pmg_battery

# replace "battery" below with the event generated on your laptop
# For example, battery.* will match battery BAT0 00000080 00000001
event=battery.*
action=/etc/acpi/actions/pmg_switch_runlevel.sh %e

最后acpid要重新启动来识别这些改变。

代码 2.10: 完成acpid运行级别切换

# /etc/init.d/acpid restart

试一下:插拔电源并查看系统的日志中"Switching to AC mode"或"Switching to battery mode"消息。如果这个脚本不能正确地检测电源状况,请参见常见问题部分

因为事件机制的特性,不管是用AC电源或是电池,你的笔记本会启动到default的运行级别中。当用AC电源启动的时候,这是好事,但如果我们需要从电池启动的话,我们就希望进入的是battery的运行级别。一个解决的办法是在内核的启动参数中加上softlevel=battery,但是它很倾向于忘记选择。一个更好的办法是在启动的最后假造一个ACPI事件,让pmg_switch_runlevel.sh脚本决定是否需要切换运行级别。用你喜欢的文本编辑器打开/etc/conf.d/local.start并加入下面几行:

代码 2.11: 编辑local.start以实现启动时运行级别的调整

# Fake acpi event to switch runlevel if running on batteries
/etc/acpi/actions/pmg_switch_runlevel.sh "battery/battery"

像这样准备,你就可以为单独的设备激活电源管理策略。

3.  CPU电源管理

移动处理器能够在不同的主频下运行。有些则允许改变电压。大多数情况下,你的CPU不需要全速运行,将它的主频降下来可以节省很多电量——经常是不牺牲任何性能。

一些技术术语

你可能对CPU降频相关的一些术语不是很清楚,这里是一个简介。

首先,内核需要能够改变处理器的主频。CPUfreq processor driverCPU主频驱动知道用来在你的CPU上的相应命令。所以在你的内核中选择正确的驱动是很重要的。你应该在上面就已经完成了。一旦内核知道如何改变主频,它就需要知道它应该设置哪个主频。这是根据policy,即策略来完成的,它由CPUfreq policyCPU主频策略governor管理器组成。CPU主频策略是定义CPU主频范围的两个值——最大主频和最小主频。管理器则决定选择最大最小值间的哪一个可用的主频。例如,powersave governor总是选择可用的最低主频,而performance governor则总选择最高的主频。userspace governor并不做决定,而是取用户(或者是用户控制的程序)想要的——即从/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed中读取。

这听起来不像是动态的主频改变而且事实上它的确不是动态的,不过可以通过多种途径实现。例如ondemand governor根据当前的CPU负载来做决定。同样的任务可以由许多用户端的程序来完成,如cpudyncpufreqdpowernowd等等。ACPI事件则可以用来根据电源情况,启用或禁用动态降频。

设定主频

降低CPU的速度和电压有两个好处:首先耗电比较小,其次发热量也会比全速运行时有所改善。显然,缺点是你会损失一些性能。可以说降低处理器的速度是一种性能和省电上的均衡。

注意: 并非所有的笔记本都支持主频的改变。如果不确定,那就看一下常见问题中支持降频的处理器的列表有没有你的CPU。

现在让我们来测试一下你CPU降频能不能工作。让我们装上另一个工具:sys-power/cpufrequtils

代码 3.1: 确定CPU主频

# emerge cpufrequtils
# cpufreq-info

这是一个输出的例子:

代码 3.2: cpufreq-info的输出例子

cpufrequtils 0.3: cpufreq-info (C) Dominik Brodowski 2004
Report errors and bugs to linux@brodo.de, please.
analyzing CPU 0:
  driver: centrino
  CPUs which need to switch frequency at the same time: 0
  hardware limits: 600 MHz - 1.40 GHz
  available frequency steps: 600 MHz, 800 MHz, 1000 MHz, 1.20 GHz, 1.40 GHz
  available cpufreq governors: conservative, ondemand, powersave, userspace, performance
  current policy: frequency should be within 924 MHz and 1.40 GHz.
    The governor "performance" may decide which speed to use
    within this range.
  current CPU frequency is 1.40 GHz.

现在让我们用cpufreq-set来折腾一下来看看主频调整能否工作。比如,运行一下cpufreq-set -g ondemand来激活ondemand管理器,然后用cpufreq-info来确认一下。如果它没有像预期的那样工作,你或许可以从指导末尾的常见问题部分中找到答案。

cpufrequtils能够以自动模式运行(当你使用ondemand管理器的时候),当你是想手动设置特定主频的时候,你也可以切换到userspace管理器。你也可以静态地用performancepowersave分别将CPU的主频设为最高或最低。

代码 3.3: 改变CPU主频

(设为可用的最高主频)
# cpufreq-set -g performance
(设为可用的最低主频)
# cpufreq-set -g powersave
(设为特定主频)
# cpufreq-set -g userspace
# cpufreq-set -f 2.00ghz

其他CPU主频工具

虽然cpufrequtils可能是最全面的程序了,但Portage中还有其他选择。下面的表格是可用CPU主频工具的速览。它可以简要地分为三类:内核类,即需要内核支持;后台类,即用运行在后台的程序来实现;图形界面类,即提供图形界面方便用户设置和调整。

名称 类别 调整依据 内核管理器 进一步的管理器 评价
'ondeman'管理器 内核类 CPU负载 未知 未知 当CPU有负载的时候选用最大的主频,当CPU空闲的时候一步步降低。通过/sys/devices/system/cpu/cpu0/cpufreq/ondemand/做进一步的设置。依然需要用户方面的工具(程序或脚本)来完成管理器的变更或类似的任务。
'conservative'管理器 内核类 CPU负载 未知 未知 和ondemand管理器不同的是,在CPU负载高的时候conservative并不直接跳上最高的主频,而是采用步进的方式来升高主频。
cpudyn 后台程序 CPU负载 Performance,powersave 动态 同时支持硬盘的挂起——但是laptop mode在大多数情况下会做得更好。
cpufreqd 后台程序 电池状况、CPU负载、温度、运行的程序等等 全部可用 没有 成熟的(但稍显复杂)的设置。可以通过传感器插件(lm_sensors)扩展或同一些NVidia显卡的显存或核心协作。Cpufreqd是支持SMP(对称多CPU)的,同时可以选择在运行时手动控制。
powernowd 后台程序 CPU负载 没有 被动、正弦、激进的 支持SMP
ncpufreqd 后台程序 温度 没有 Powersave、performance 根据系统的温度在performance和powersave管理器间切换。对于那些发热量声名狼藉的笔记本很有用。
speedfreq 后台程序 CPU负载 没有 动态、powersave、performance、固定速度 方便地通过客户端/服务器界面设置。要求用2.6的内核。不再被维护,有错误而从Portage中移除了。如果你还在用它,请改用cpufreqd。
gtk-cpuspeedy 图形界面 没有 没有 没有 Gnome程序,一个图形界面的工具让你手动设置CPU主频。没有提供任何自动的功能。
klaptopdaemon 图形界面 电池状态 全部可用 没有 仅支持KDE,需要'ondemand'管理器以动态降频。

虽然根据负载来调整主频看似简单。但是不好的算法可能会导致CPU不断地在两个主频间振荡,或者在不必要的高主频上浪费电量。

选择哪个?如果你拿不定主意,试试cpufreqd

代码 3.4: 安装cpufreqd

# emerge cpufreqd

cpufreqd可以通过编辑/etc/cpufreqd.conf来设置。cpufreqd自带的默认配置文件可能稍显复杂。我建议你用Gentoo的前开发人员Henrik Brix Andersen的设置来替换它(见下文)。请注意,你需要使用cpufreqd-2.0.0或以上的版本。更早的版本的设置格式是不同的。

代码 3.5: /etc/cpufreqd.conf(cpufreqd-2.0.0或以上)

[General]
pidfile=/var/run/cpufreqd.pid
poll_interval=3
enable_plugins=acpi_ac, acpi_battery
enable_remote=1
remote_group=wheel
verbosity=5
[/General]

[Profile]
name=ondemand
minfreq=0%
maxfreq=100%
policy=ondemand
[/Profile]

[Profile]
name=conservative
minfreq=0%
maxfreq=100%
policy=conservative
[/Profile]

[Profile]
name=powersave
minfreq=0%
maxfreq=100%
policy=powersave
[/Profile]

[Profile]
name=performance
minfreq=0%
maxfreq=100%
policy=performance
[/Profile]

[Rule]
name=battery
ac=off
profile=conservative
[/Rule]

[Rule]
name=battery_low
ac=off
battery_interval=0-10
profile=powersave
[/Rule]

[Rule]
name=ac
ac=on
profile=ondemand
[/Rule]

现在你可以启动cpufreqd后台程序了。把它加到defaultbattery的运行级别上。

代码 3.6: 启动cpufreqd

# rc-update add cpufreqd default battery
# /etc/init.d/cpufreqd start

有时候你想手动选择其它的策略而不是按后台程序做的,比如当电池电量已经很低了,但是你知道很快就有电源了。在这种情况下你可以通过cpufreqd-set manual来启动cpufreqd的手动模式,然后选择一个你设置的模式(可以通过cpufreqd-get列出)。你也可以通过执行cpufreqd-set dynamic离开手动模式。

警告: 不要同时运行多个上述的程序,不然可以会出现一直在两个主频间切换的奇怪现象。

确定一下结果

最后检查一下你的新策略能很好地工作。一个简单的办法就是监控一下你的笔记本CPU的工作频率:

代码 3.7: 监控CPU频率

# watch grep \"cpu MHz\" /proc/cpuinfo

如果/proc/cpuinfo没有更新的话(参见常见问题),用sys-apps/x86info来监控CPU频率:

代码 3.8: CPU频率监控备用方案

# watch x86info -mhz

根据你的设置,CPU频率应该在高负载时升高,没负载的时候下降或保持不变。如果你用的是cpufreqd并且在cpufreqd.conf中将verbosity设为5或更高,你就能从syslog中获得额外的报告信息。

4.  LCD电源管理

正如你在figure 1.1中看到的,LCD是最大的耗电大户(对于非移动的CPU可能不适用)。所以不需要的时候把显示器关掉是非常重要的,可能的话降低它背光的亮度。大多数笔记本都可能控制背光的亮度。

挂起设置

首先检查一下你显示器挂起/休眠/关闭的时间设置。因为这跟你使用的窗口管理器有很大的关系,我将让你自己搞清楚。一般只有两个地方:可以通过setterm -blank <number-of-minutesM>setterm -powersave onsetterm -powerdown <number-of-minutesM>来变暗终端。对于X.org,修改/etc/X11/xorg.conf中的类似配置:

代码 4.1: X.org中LCD挂起的设置

Section "ServerFlags"
  Option  "blank time"  "5"  # Blank the screen after 5 minutes (Fake)
  Option  "standby time"  "10"  # Turn off screen after 10 minutes (DPMS)
  Option  "suspend time"  "20"  # Full suspend after 20 minutes
  Option  "off time"  "30"  # Turn off after half an hour
  [...]
EndSection

[...]

Section "Monitor"
  Identifier  [...]
  Option  "DPMS"
  [...]
EndSection

背光亮度

可能更重要的是背光亮度。如果你需要通过工具来设置背光亮度,就写一个脚本来调低电池模式下的亮度,并把它放到你的battery运行级别中。下面这个脚本应该适用于大多数的IBM Thinkpad和东芝的笔记本。你需要设置一些相应的内核选项(IBM Thinkpad的情况)。对于东芝的笔记本,装上sys-power/acpitool并跳过下面的thinkpad_acpi(以前叫ibm_acpi)设置。

警告: 设置背光在thinkpad_acpi中是试验性的。它直接控制硬件并可能对你的系统造成严重的损坏损坏。请阅读thinkpad_acpi的主页

为了可以设置亮度,thinkpad_acpi模块要用experimental参数加载。

代码 4.2: 自动加载thinkpad_acpi模块

(请先阅读上面的警告再做这个!)
# echo "options thinkpad_acpi experimental=1" >> /etc/modules.d/thinkpad_acpi
# update-modules
# echo thinkpad_acpi >> /etc/modules.autoload.d/kernel-2.6
# modprobe thinkpad_acpi

这样应该就可以不用看到警告信息并在模块加载后生成/proc/acpi/ibm/brightness文件。通过一个启动脚本就可以根据电源的情况调节亮度了。

代码 4.3: /etc/conf.d/lcd-brightness

# See /proc/acpi/ibm/brightness for available values
# Please read /usr/src/linux/Documentation/thinkpad-acpi.txt

# brightness level in ac mode. Default is 7.
BRIGHTNESS_AC=7

# brightness level in battery mode. Default is 4.
BRIGHTNESS_BATTERY=4

代码 4.4: /etc/init.d/lcd-brightness

#!/sbin/runscript

set_brightness() {
    if on_ac_power
    then
        LEVEL=${BRIGHTNESS_AC:-7}
    else
        LEVEL=${BRIGHTNESS_BATTERY:-4}
    fi

    if [ -f /proc/acpi/ibm/brightness ]
    then
        ebegin "Setting LCD brightness"
        echo "level ${LEVEL}" > /proc/acpi/ibm/brightness
        eend $?
    elif [[ -e /usr/bin/acpitool && -n $(acpitool -T | grep "LCD brightness") ]]
    then
        ebegin "Setting LCD brightness"
        acpitool -l $LEVEL >/dev/null || ewarn "Unable to set lcd brightness"
        eend $?
    else
        ewarn "Setting LCD brightness is not supported."
        ewarn "For IBM Thinkpads, check that thinkpad_acpi is loaded into the kernel"
        ewarn "For Toshiba laptops, you've got to install sys-power/acpitool"
    fi
}

start() {
    set_brightness
}

stop () {
    set_brightness
}

当完成后,确认亮度可以按照电源情况自动调节后,把它加到battery运行级别中。

代码 4.5: 开启亮度自动调节

# chmod +x /etc/init.d/lcd-brightness
# rc-update add lcd-brightness battery
# rc

5.  硬盘电源管理

硬盘在休眠状态下消耗较少的电量。所以当硬盘未使用一定时间后,激活硬盘的节电模式是合理的。我将告诉你两个可能的方式来实现它。首先,laptop-mode可以通过避免或延迟写硬盘而节约大量电量。缺点是延迟写硬盘可能在电量耗尽或内核崩溃时造成数据丢失。如果你不喜欢那样,你就需要确定没有进程频繁地写硬盘。第二个选择,你可以通过hdparm来启用你硬盘的节电模式。

延长空闲时间——laptop-mode

最近的2.6内核包含了据称的laptop-mode。当被激活时,修改过的缓存就在读磁盘的时候写入,或在10分钟后写入(原先是30秒)。这样就你硬盘需要转动的次数最小化。

代码 5.1: 自动启动laptop-mode

# emerge laptop-mode-tools

laptop-mode-tools的设置文件是/etc/laptop-mode/laptop-mode.conf。根据你喜欢的方式修改它,它已经注释得很好了。运行rc-update add laptop_mode battery让它自动启动。

laptop-mode-tools的最近版本(1.11或以上)包含了一个新的工具lm-profiler。它会监视你系统中磁盘的使用和网络服务,并建议你关掉不需要的。你既可以通过laptop-mode-tools中内置的运行级别支持(会被Gentoo的/sbin/rc重置)或用你的default/battery运行级别(推荐)

代码 5.2: 运行lm-profiler的输出示例

# lm-profiler
Profiling session started.
Time remaining: 600 seconds
[4296896.602000] amarokapp
Time remaining: 599 seconds
[4296897.714000] sort
[4296897.970000] mv
Time remaining: 598 seconds
Time remaining: 597 seconds
[4296900.482000] reiserfs/0

当分析你的系统10分钟后,lm-profiler就会列出这段时间内可能造成磁盘访问的服务。

代码 5.3: lm-profiler建议禁用一些服务

Program:     "atd"
Reason:      standard recommendation (program may not be running)
Init script: /etc/init.d/atd (GUESSED)

Do you want to disable this service in battery mode? [y/N]: n

在上面例子中,根据建议禁用atd,你可以运行rc-update del atd battery。注意不要禁用你系统正常工作需要的服务。不要禁用你不清楚的服务。

Limiting Write Accesses

如果你不想用laptop-mode,你就需要特别小心地禁用那些频繁读磁盘的程序——syslogd是一个很好的例子。你可能不想将完全它关掉,但你可以修改它的设置文件,这样"不需要"的东西就不会被记入日志,也就不会导致硬盘访问。Cups会周期性地写磁盘,所以可以考虑将它关掉,需要的时候再手动启动。

代码 5.4: 在battery运行级别中关闭cpus

# rc-update del cupsd battery

你也可以用laptop-mode-tools(见上文)中的lm-profiler来找出要禁用的服务。当你完成后,向配置hdparm继续。

hdparm

第二个可能是用hdparm。如果你已经用了laptop-mode就跳过这部分。不然,就编辑/etc/conf.d/hdparm并为你的磁盘驱动器加入下列的值。这个例子假设你的硬盘是hda

代码 5.5: 用/etc/conf.d/hdparm来挂起磁盘

hda_args="-q -S12"

这样你就可以激活你硬盘的电源管理。如果你想关闭其电源管理,你可以编辑/etc/conf.d/hdparm,把值改为-q -S0,或直接运行hdparm -q -S0 /dev/hda

查看man hdparm中更多的选项。虽然你可以在battery的运行级别中通过/etc/init.d/hdparm start手动开启hdparm,但让它自动开启和关闭比较轻松些。把hdparm加到battery的运行级别中它就可以自动启动电源管理了。

代码 5.6: 自动启动硬盘挂起设置

# rc-update add hdparm battery

重要: 注意你硬盘的睡眠/停转的设定。把它设得太小可能会损耗你的硬盘。

其他的技巧

另外的就是在电池模式下关闭你的swap。在运行swapon/swapoff的切换前,先确定有足够的内存且swap没有使用很多,不然你可能会有大麻烦。

如果你不想使用laptop-mode,你依然可以通过把一些特定的目录以tmpfs挂载来最小化磁盘的读写,此时写的操作不是在磁盘上的,而是在内存中,并且umount后就丢失了。一般情况下,把/tmp像这样挂载是不错的选择——它会在每次重启的时候被清空,无论是挂载在硬盘上还是内存中。激活它,你需要在内核中启动tmpfs的支持,并在/etc/fstabl中加入如下的一行:

代码 5.7: 编辑/etc/fstab使/tmp更飞速

none  /tmp  tmpfs  size=32m  0 0

警告: 请注意size参数并根据你的系统来修改它。如果你不确定,就不要使用它,它很容易成为一个性能瓶颈。如果你想把/var/log像这样挂载,一定要在umount前把日志文件写入磁盘。它们非常重要。不要试图像这样挂载/var/tmp。Portage用它来编译......

6.  其他设备的电源管理

显卡

如果你用的是支持PowerPlay(显卡核心GPU的动态时钟调整)的ATI显卡,你可以在X.org中启用它。打开/etc/X11/xorg.conf并在Device中加入(或启用)DynamicClocks选项。注意,这个选项可能会导致一些系统崩溃。

代码 6.1: 在X.org中启用ATI的PowerPlay支持

Section "Device"
[...]
Option      "DynamicClocks" "on"
EndSection

无线的电源管理

无线网卡消耗了一定的电量。把它们像硬盘一样纳电源管理模式中。

注意: 这个脚本假设你的无线网卡是wlan0;请把它改成你的机子上的真实网卡

把下面的选项加到/etc/conf.d/net中以自动启用无线网卡的电源管理:

代码 6.2: 无线网卡的自动电源管理

iwconfig_wlan0="power on"

查看man iwconfig以获得更多细节和更多的选项,如唤醒的周期和超时。如果你驱动和接入点支持改变信标(beacon)的发送间隔,那它就可以节省更多的电量。

USB电源管理

关于USB电源消耗有两个问题:第一,USB鼠标、数码相机或U盘在插入的时候都会耗电。你可以避免这个问题(当它们不用的时候,不要移除它们)。第二,当有USB设备插入的时候,USB控制器会周期性地访问接口从而阻止CPU进入睡眠模式。内核提供了一个试验性的选项通过/sys中的power/state来启用USB设备的挂起。

代码 6.3: 在内核中启用USB设备的挂起

Device Drivers
  USB support
    [*]   Support for Host-side USB
      [*]   USB suspend/resume (EXPERIMENTAL)

7.  睡眠状态:挂起、待机、休眠(到磁盘)

ACPI定义了不用的睡眠状态。其中比较重要的是

  • S1即待机
  • S3即挂起到内存,即挂起
  • S4即挂起到磁盘,即休眠

它们可以系统没有使用但又不想关机的时候调用。

挂起(S3)

ACPI对这些睡眠状态的支持标记为试验性的是有原因的。APM的睡眠状态看起来更稳定些,但你不能将APM和ACPI同时使用。

代码 7.1: 各种睡眠状态的内核设置

  Power Management Options --->
    [*]  Power Management support
    [*]  Suspend to RAM and standby

当你正确设置内核后,你就可以用hibernate-script来激活挂起或待机模式。让我们先将它装起来。

代码 7.2: 安装hibernate-script

# emerge hibernate-script

一些设置需要在/etc/hibernate中完成。

设置挂起的话,编辑/etc/hibernate中的sysfs-ram.confUSESysfsPowerState mem总是对的,但是如果你需要对挂起(或其他睡眠状态)做更进一步的设置,你应该把它们加到/etc/hibernate/hibernate.conf中。里面的注释和选项的名称应该可以指引你的。如果你使用网络共享的nfs或samba,确保你关掉相应的启动脚本来避免超时。

注意: 关于睡眠状态更多的信息,参见man hibernate.conf

准备好了吗?现在是你运行下个命令前备份任何数据的最后机会了。注意,你可能需要按一个特殊的键如Fn来从挂起中恢复。

代码 7.3: 挂起

# hibernate-ram

如果你仍在往下读,那上面的可能没有问题。你也可以类似地设置待机(S1)。修改sysfs-ram.conf,把"UseSysfsPowerState men"改为"UseSysfsPowerState standby"。S3和S4是更有吸引力的睡眠状态,因为它们能节省更多的电量。

休眠(S4)

这部分介绍休眠,它把当前运行的系统的镜像在关机前写入磁盘。当恢复的时候,镜像就被加载,你就可以在你休眠前的工作点继续了。

警告: 在休眠中不要改变不可热插拔的硬件。不要试图加载另外一个内核的镜像。在休眠前关闭任何NFS或sambla的服务端/客户端。

现在有两个支持S4的方法。最初的一个是swsusp,另一个新的是带有漂亮界面(带有fbsplash支持)的tuxonice(之前的suspend2)。一份特性对比可以在tuxonice主页上找到。曾经有一个挂起到硬盘(pmdisk),一个从swsusp分支出来的项目,后来又合并回去了。

TuxOnIce并未包含在主流的内核中,所以你既可以用tuxonice.net提供的patch给内核打补丁,也可以用sys-kernel/tuxonice-sources

swusp和TuxOnIce在内核中的部分如下:

代码 7.4: 各种睡眠状态的内核设置

Power management support --->
  (hibernate with swsusp)
  [*] Hibernation (aka 'suspend to disk')
      (replace /dev/SWAP with your swap partition)
      (/dev/SWAP)      Default resume partition

  (hibernate with TuxOnIce)
  Enhanced Hibernation (TuxOnIce)
    --- Image Storage (you need at least one allocator)
    [*]    File Writer
    [*]    Swap Writer
    ---   General Options
    [*]    Compression support
    [ ]     Allow Keep Image Mode
    [*]     Replace swsusp by default

swsusp的设置非常简单。如果你没有把储存用的swap位置写在内核的配置中,就把它作为内核参数resume=/dev/SWAP直接传递。如果引导因为镜像损坏而不能运行,就用noresume内核参数。hibernate-cleanup启动脚本会使swsusp的镜像在启动中失效。

代码 7.5: 使swsusp镜像在启动中失效

# rc-update add hibernate-cleanup boot

激活swsusp的休眠,你需要在/etc/hibernate/sysfs-disk中设置UseSysfsPowerState disk并使用休眠脚本。

警告: 在开始做这步之前备份你的数据。运行在下面的命令前执行sync将缓存的数据写入磁盘。首先在X外尝试,接着在X运行但没有登陆时。

如果你遇到因为uhci或类似模块导致的内核的错误,试着将它们编译成模块,然后将它们卸载后再进入睡眠模式。其相应的设置在common.conf中。

代码 7.6: 用swsusp休眠

# nano -w /etc/hibernate/common.conf
(确定你已经备份好你的数据了)
# hibernate

接下来的部分讨论如何设置TuxOnIce在挂起和恢复中用漂亮的fbsplash。

前面的设置部分和swsusp类似。如果你没有把你swap分区的位置记录在内核配置中,你需要把它作为内核参数resume=swap:/dev/SWAP直接传递。如果内核因为损坏的镜像而不能启动,加上noresume参数。另外,hibernate-cleanup会让TuxOnIce的镜像在启动中失效。

代码 7.7: 使TuxOnIce的镜像在启动中失效

# rc-update add hibernate-cleanup boot

现在编辑/etc/hibernate/tuxonice.conf,启动你需要的TuxOnIce选项。但现在先不要在common.conf中启用fbsplash选项。

代码 7.8: 用TuxOnIce休眠

# nano -w /etc/hibernate/tuxonice.conf
(确定你已经备份好你的数据了)
# hibernate

请配置fbsplash,如果你还没有配置好。启用休眠中fbsplash的支持,你需要sys-apps/tuxonice-userui。另外,你需要启用fbsplash的USE标记。

代码 7.9: 安装tuxonice-userui

# echo "sys-apps/tuxonice-userui fbsplash" >> /etc/portage/package.use
(它可能被~arch屏敝屏蔽了,所以你需要为它启用keywords)
# echo "sys-apps/tuxonice-userui" >> /etc/portage/package.keywords
# emerge tuxonice-userui

它的ebuild告诉你得生成一个链接到你想用的主题。例如,使用livecd-2005.1的主题,运行下面的命令:

代码 7.10: 在休眠中使用livecd-2005.1的主题

# ln -sfn /etc/splash/livecd-2005.1 /etc/splash/tuxonice

如果你不想在最初恢复时看到黑屏,你就需要把tuxoniceui_fbsplash加到你的initrd镜像中。假设你用splash_geninitramfs生成了一个initrd镜像,并将其保存为/boot/fbsplash-emergence-1024x768,下面将告诉你怎样做。

代码 7.11: 将tuxoniceui_fbsplash加到initrd中

# mount /boot
# mkdir ~/initrd.d
# cp /boot/fbsplash-emergence-1024x768 ~/initrd.d/
# cd ~/initrd.d
# gunzip -c fbsplash-emergence-1024x768 | cpio -idm --quiet -H newc
# rm fbsplash-emergence-1024x768
# cp /usr/sbin/tuxoniceui_fbsplash sbin/
# find . | cpio --quiet --dereference -o -H newc | gzip -9 > /boot/fbsplash-tuxonice-emergence-1024x768

之后调整一下grub.conf(或 lilo.conf)使你的TuxOnIce内核使用/boot/fbsplash-tuxonice-emergence-1024x768作为initrd镜像。你可以测试一下看是否设置正确。

代码 7.12: fbsplash休眠测试

# tuxoniceui_fbsplash -t

在打开/etc/hibernate/common.conf并激活fbsplash选项后。执行hibernate然后享受吧。

8.  常见问题

问:我试着改变CPU的主频,但是/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor不存在。

答:确认你的处理器支持降频且你选择了正确的CPU频率驱动。这里是一份cpufreq(内核2.6.7)支持的处理器清单:ARM Integrater、ARM-SA1100、ARM-SA1110、AMD Elan-SC400、SC410、AMD mobile K6-2+、AMD mobile K6-3+、AMD mobile Duron、AMD mobile Athlon、AMD Opteron、AMD Athlon 64、Cyrix Media GXm、Intel mobile PIII及一些特定芯片组上的Intel mobile PIII-M、Intel Pentium 4、Intel Xeon、Intel Pentium M(Centrino)、National Semiconductors Geode GX、Transmeta Crusoe、VIA Cyrix 3/C3、UltraSPARC-III、SuperH SH-3、SH-4、许多"PowerBook"和"iBook2"及一些ACPI 2.0兼容系统上的处理器(当且仅当"ACPI Processor Performance States"对ACPI/BIOS可用的时候)。

问:我的笔记本支持降频,但/sys/devices/system/cpu/cpu0/cpufreq/是空的。

答:dmesg | grep ACPI查看ACPI相关的错误信息。试着升级BIOS,特别有报告是DSDT损坏时。你也可以试着自己修复它(不在本篇的讨论范围内)。

问:我的笔记本支持降频,但根据/proc/cpuinfo主频并没有改变。

答:可能你在内核中启用了对称多处理器支持(CONFIG_SMP)。禁用它应该就可以了。一些旧的内核有一个bug导致这个问题。这种情况下,你可以执行emerge x86info,根据要求升级你的内核并用x86info -mhz检查CPU的主频。

问:我可以改变CPU的主频,但范围没有其他操作系统那么大。

答:你可以将降频和ACPI节流(throttling)结合使用来获得更小的最低频率。注意,节流并不会节省很多电量,它主要的用于热量管理的(让你的笔记本保持安静和较低的温度)。你可以通过cat /proc/acpi/processor/CPU/throttling来知道当前的节流,并通过 echo -n "0:x" > /proc/acpi/processor/CPU/limit来设定,这里的x是/proc/acpi/processor/CPU/throttling中列出的Tx状态值中的一个。

问:当配置内核的时候,有pwersave,performance和userspace,但ondemand却没有。我在哪里可以找到它?

答:ondemand管理器仅在最近的内核中有,试着升级一下内核。

问:电池的使用时间好像比以前更差了。

答:检查一下你BIOS的设定。可能你忘了重新开启一些设定了。

问:我的电池已经充满,但KDE报告说仅剩0%的电量,然后迅速关机了。

答:检查一下你内核中的电池支持。如果你将它编译成模块,确认你已经加载它了。

问:我系统日志报告一些像这样的东西"logger: ACPI group battery / action battery is not definded"。

答:这条信息是由acpid的/etc/acpi/default.sh脚本生成的。你可以安全地忽略它。如果你想要去除它,你可以将相应的行从/etc/acpi/default.sh中注释掉,如下所示:

代码 8.1: 禁用unkown acpi事情警告

        *)      # logger "ACPI action $action is not defined"

我有一台Dell Inspiron 51XX但我得不到任何ACPI事件。

这貌似是一个内核的bug。参见这里

问:我激活了xorg.conf中的DynamicClocks选项,结果现在X.org崩溃了/黑屏/我的笔记本不能正常关机。

答:这出现在一些系统上。你不得不禁用DynamicClocks

问:我想用TuxOnIce,但它告诉我说我的swap分区太小了。但重新分区不可行。

答:如果你的系统中有足够大的空闲空间,你可以用文件形式(filewriter)而不用swap形式(swapwriter)。hibernate-script能很好地支持。更多的信息可以在/usr/src/linux/Documentation/power/tuxonice.txt中找到。

问:我刚刚买了一个新的电池,但它只持续了几分钟!我做错了什么?

答:首先按制造商的建议对电池正确充电。

问:上面的办法没有用。我还能做什么?

答:有一些电池声称是"新"的但实际上是旧的。试着这么做:

代码 8.2: 检查电池的状态

$ grep capacity /proc/acpi/battery/BAT0/info
design capacity:     47520 mWh
last full capacity:  41830 mWh

如果"last full capacity"和"design capacity"有很大的不同,你的电池很可能已经损坏了。试着要求保修吧。

问:我的问题没有在上面列出。我接下来应该怎么做?

答:不要担心直接联系我,Dennis NienhüserGentoo Forums也是一个获得帮助的好地方。如果你更喜欢IRC,试试 #gentoo-laptop频道



打印

更新于2010年 7月 13日

本翻译的原始版本已经不再被维护

总结: 电源管理是延长移动系统上电池使用时间的关键,比如在笔记本电脑上。这篇指导将帮你在你的笔记本上设置它。

Dennis Nienhüser
作者

Chris White
编辑

Joshua Saddler
编辑

余钰炜
译者

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.