Power Management Guidehttp://www.gentoo.org/doc/en/power-management-guide.xml

1. Introduction

Capacity and lifetime of laptop batteries have improved much in the last years. Nevertheless modern processors consume much more energy than older ones and each laptop generation introduces more devices hungry for energy. That's why Power Management is more important than ever. Increasing battery run time doesn't necessarily mean buying another battery. Much can be achieved applying intelligent Power Management policies.

A Quick Overview

Please notice that this guide describes Power Management for laptops. While some sections might also suite for servers, others do not and may even cause harm. Please do not apply anything from this guide to a server unless you really know what you are doing.

As this guide has become rather long, here's a short overview helping you to find your way through it.

The Prerequisites chapter talks about some requirements that should be met before any of the following device individual sections will work. This includes BIOS settings, kernel configuration and some simplifications in user land. The following three chapters focus on devices that typically consume most energy - processor, display and hard drive. Each can be configured seperately. CPU Power Management shows how to adjust the processor's frequency to save a maximum of energy without losing too much performance. A few different tricks prevent your hard drive from working unnecessarily often in Disk Power Management (decreasing noise level as a nice side effect). Some notes on graphics cards, Wireless LAN and USB finish the device section in Power Management For Other Devices while another chapter is dedicated to the (rather experimental) sleep states. Last not least Troubleshooting lists common pitfalls.

Power Budget For Each Component


Figure 1.1: Power budget for each component

Power Management Guide[不全版 因为百度的字数限制原因]_#Gentoo

Nearly every component can operate in different states - off, sleep, idle, active to name a few - consuming a different amount of energy. Major parts are consumed by the LCD display, CPU, chipset and hard drives. Often one is able to activate OS-independent Power Management in the BIOS, but an intelligent setup in the operating system adapting to different situations can achieve much more.

2. Prerequisites

Before discussing the details of making individual devices Power Management aware, make sure certain requirements are met. After controlling BIOS settings, some kernel options want to be enabled - these are in short ACPI, sleep states and CPU frequency scaling. As power saving most of the time comes along with performance loss or increased latency, it should only be enabled when running on batteries. That's where a new runlevel battery comes in handy.

The BIOS Part

First have a look into your BIOS Power Management settings. The best way is to combine BIOS and operating system policies, but for the moment it's better to disable most of the BIOS part. This makes sure it doesn't interfere with your policies. Don't forget to re-check BIOS settings after you configured everything else.

Setting USE Flags

Please check that the acpi USE flag is set in /etc/make.conf. Other USE flags that might be interesting for your system are apm, lm_sensors, nforce2, nvidia, pmu. See /usr/portage/profiles/use*.desc for details. If you forgot to set one of these flags, you can recompile affected packages using the --newuse flag in emerge, see man emerge.

Configuring The Kernel

ACPI (Advanced Configuration and Power Interface) support in the kernel is still work in progress. Using a recent kernel will make sure you'll get the most out of it.

There are different kernel sources in Portage. I'd recommend using gentoo-sources or tuxonice-sources. The latter contains patches for TuxOnIce, see the chapter about sleep states for more details. When configuring the kernel, activate at least these options:

Code Listing 2.1: Minimum kernel setup for Power Management (Kernel 2.6)

Power Management Options --->
[*] Power Management Support
[ ] Software Suspend

ACPI( Advanced Configuration and Power Interface ) Support --->
[*] ACPI Support
[ ] Sleep States
[ ] /proc/acpi/sleep (deprecated)
[*] 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

Decide yourself whether you want to enable Software Suspend, and Sleep States (see below). If you own an ASUS, Medion, IBM Thinkpad or Toshiba laptop, enable the appropriate section.

The kernel has to know how to enable CPU frequency scaling on your processor. As each type of CPU has a different interface, you've got to choose the right driver for your processor. Be careful here - enabling Intel Pentium 4 clock modulation on a Pentium M system will lead to strange results for example. Consult the kernel documentation if you're unsure which one to take.

Compile your kernel, make sure the right modules get loaded at startup and boot into your new ACPI-enabled kernel. Next run emerge sys-power/acpid to get the acpi daemon. This one informs you about events like switching from AC to battery or closing the lid. Make sure the modules are loaded if you didn't compile them into the kernel and start acpid by executing /etc/init.d/acpid start. Run rc-update add acpid default to load it on startup. You'll soon see how to use it.

Code Listing 2.2: Installing acpid

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

Creating A "battery" Runlevel

The default policy will be to enable Power Management only when needed - running on batteries. To make the switch between AC and battery convenient, create a runlevel battery that holds all the scripts starting and stopping Power Management.

Note: You can safely skip this section if you don't like the idea of having another runlevel. However, skipping this step will make the rest a bit trickier to set up. The next sections assume a runlevel battery exists.

Code Listing 2.3: Creating a battery runlevel

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

Finished. Your new runlevel battery contains everything like default, but there is no automatic switch between both yet. Time to change it.

Reacting On ACPI Events

Typical ACPI events are closing the lid, changing the power source or pressing the sleep button. An important event is changing the power source, which should cause a runlevel switch. A small script will take care of it.

First you need a script which changes the runlevel to default respectively battery depending on the power source. The script uses the on_ac_power command from sys-power/powermgmt-base - make sure the package is installed on your system.

Code Listing 2.4: Installing powermgt-base

# emerge powermgmt-base

You are now able to determine the power source by executing on_ac_power && echo AC available || echo Running on batteries in a shell. The script below is responsible for changing runlevels. Save it as /etc/acpi/actions/pmg_switch_runlevel.sh.

Code Listing 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

Dont forget to run chmod +x /etc/acpi/actions/pmg_switch_runlevel.sh to make the script executable. The last thing that needs to be done is calling the script whenever the power source changes. That's done by catching ACPI events with the help of acpid. First you need to know which events are generated when the power source changes. The events are called ac_adapter and battery on most laptops, but it might be different on yours.

Code Listing 2.6: Determining ACPI events for changing the power source

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

Run the command above and pull the power cable. You should see something like this:

Code Listing 2.7: Sample output for power source changes

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

The interesting part is the quoted string after received event. It will be matched by the event line in the files you are going to create below. Don't worry if your system generates multiple events or always the same. As long as any event is generated, runlevel changing will work.

Code Listing 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

Code Listing 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

Finally acpid has to be restarted to recognize the changes.

Code Listing 2.10: Finishing runlevel switching with acpid

# /etc/init.d/acpid restart

Give it a try: Plug AC in and out and watch syslog for the "Switching to AC mode" or "Switching to battery mode" messages. See the Troubleshooting section if the script is not able to detect the power source correctly.

Due to the nature of the event mechanism, your laptop will boot into runlevel default regardless of the AC/battery state. This is fine when running from AC, but we'd like to boot into the battery runlevel otherwise. One solution would be to add another entry to the boot loader with the parameter softlevel=battery, but it's likely to forget choosing it. A better way is faking an ACPI event in the end of the boot process and letting pmg_switch_runlevel.sh script decide whether a runlevel change is necessary. Open /etc/conf.d/local.start in your favourite editor and add these lines: