Linux ACPI-HOWTO, The Sequel
Ariel Glenn
<[1]ariel@columbia.edu>
2005-10-19
Revision
History
Revision 0.2e Revised by: atg
update [FIXME] list;
custom DSDT in kernel and in initrd; initramfs notes;
overview of
ACPI tables; lvm corrections
Revision 0.2d Revised by: atg
2.6.14-rc4; Nvidia driver with swsusp2 notes; swsusp3 notes; ACPI4Linux
wiki
live again; swsusp* comparison
Revision 0.2c Revised
by: atg
Nvidia console switching problem for swsusp1 noted;
swsusp2 notes;
2.6.14-rc3; ^T and other typos
Revision 0.2b
Revised by: atg
Software Suspend (swsusp1) notes added; Dave Jones
in credits
Revision 0.2a Revised by: atg
Clean up markup
and typos; update Jens Axboe SATA patch info; 2.6.14-rc2;
video
patch not needed
Revision 0.2 Revised by: atg
Get a laptop 4
years later and rewrite the whole fscking thing for kernel
2.6.13
Revision 0.1e Revised by: atg
Fix typos; move full text of GPL to
separate document; bug reports now go to
Andy Grover
Revision 0.1d Revised by: atg
Added information about libpopt,
required for build of acpictl (included in
acpid)
Revision
0.1c Revised by: atg
describe pmtest util, /proc interface,
reduced functionality of new acpid,
changes to driver options
This document provides an overview of the ACPI subsystem in Linux,
including
kernel configuration, acpid support daemon, supporting
user applications,
and common problems.
_________________________________________________________________
Table of Contents
1. [2]About this document
1.1.
[3]Introduction
1.2. [4]Copyright and License
1.3.
[5]Disclaimer
1.4. [6]Credits/Contributors
1.5.
[7]Feedback
1.6. [8][FIXME]s
2. [9]Overview of ACPI
2.1. [10]What is power management?
2.2. [11]What is ACPI?
2.3. [12]What is the difference between ACPI and APM?
2.4.
[13]What ACPI capabilities are supported under Linux?
3.
[14]Hardware requirements
3.1. [15]What hardware is
supported?
3.2. [16]What devices are supported?
3.3. [17]Which BIOSes are supported?
3.4. [18]How can I tell
if my BIOS supports ACPI?
3.5. [19]When will my (unsupported)
laptop be supported?
4. [20]Software requirements
4.1. [21]Which kernels are supported?
4.2. [22]What are the
latest acpi driver / supporting utilities and
where
can I get them?
4.3. [23]Are binary distributions
available?
5. [24]Compilation and installation
5.1. [25]Prerequisites and kernel setup
5.2. [26]Useful BIOS
settings
5.3. [27]Boot parameters
6. [28]The acpid
event handling daemon
6.1. [29]What is acpid and where do
I get it?
6.2. [30]How do I build and install acpid?
6.3. [31]How do I use acpid?
6.4. [32]What events will acpid
respond to?
6.5. [33]How can I keep track of what acpid
thinks it's doing?
6.6. [34]Where can I find other cool acpid
scripts?
7. [35]CPU management under ACPI
7.1.
[36]CPU management overview
7.2. [37]CPU idle power states
7.3. [38]CPU frequency management
7.4. [39]CPU throttling
8. [40]Thermal management
8.1. [41]Overview of thermal
management
8.2. [42]What are thermal zones?
8.3.
[43]What are cooling modes and how do I change them?
8.4.
[44]What are trip points and how do I set them?
8.5. [45]What
are throttling/performance state limits and how do I use
them?
9. [46]ACPI generic hotkey driver
9.1.
[47]What is the generic hotkey driver and how do I use it?
9.2. [48]How can I tell if my laptop supports the generic hotkey
driver?
9.3. [49]How can I get the ACPI event number for
my hotkey?
9.4. [50]How do I set up a hotkey function?
9.5. [51]What are the hotkey driver event numbers?
9.6.
[52]What should acpid do after I press a hotkey?
9.7.
[53]Where do I find ACPI bus names and device paths?
10.
[54]Suspend to RAM
10.1. [55]How do I suspend to RAM?
10.2. [56]My video isn't working; what now?
10.3. [57]What
utilities are there that I can use for this?
10.4. [58]How
about suspend to RAM when I close my laptop?
10.5. [59]My
usb/pcmcia/other device doesn't work when the system
resumes; what can I do?
10.6. [60]Suspend to RAM just
doesn't work after everything I've tried;
what now?
11. [61]Suspend to disk
11.1. [62]How do I suspend to
disk?
11.2. [63]Which should I use, swsusp1, swsusp2, or
swsusp3?
11.3. [64]What utilities are there that I can use
for this?
11.4. [65]My usb///other device doesn't work when
the system resumes;
what can I do?
11.5. [66]Suspend to disk just doesn't work after everything I've
tried; what now?
12. [67]Vbetool
12.1.
[68]What is vbetool and where do I get it?
12.2. [69]How do I
build vbetool?
12.3. [70]How do I use vbetool?
13.
[71]Patches
13.1. [72]SATA driver
13.2.
[73]Radeonfb patches
13.3. [74]VGA post
13.4.
[75]Ethernet cards
13.5. [76]Yenta CardBus socket
14. [77]Debugging tips
14.1. [78]The driver isn't working
right for me. How can I figure out
what's wrong?
14.2. [79]DSDT editing
14.3. [80]Last ditch efforts
14.4. [81]Submitting useful bug reports
15. [82]Extracting
ACPI tables with pmtools
15.1. [83]Compilation and
installation of pmtools
15.2. [84]Using pmtools
16.
[85]ASL compiler / AML disassembler iasl
16.1. [86]What
is iasl and where do I get it?
16.2. [87]How do I build iasl?
16.3. [88]How do I use iasl?
17. [89]dmidecode
17.1. [90]What is dmidecode and where do I get it?
17.2.
[91]How do I compile and install dmidecode?
17.3. [92]How do I
use dmidecode?
18. [93]ACPI details
18.1.
[94]What are all these power states C1, S4, D3, etc?
18.2.
[95]What are all these ACPI tables, DSDT, FADT, and so on?
19.
[96]Other information sources
19.1. [97]Mailing lists
19.2. [98]ACPI on Linux laptops
19.3. [99]Other HOWTOS
19.4. [100]Useful papers
19.5. [101]Official specifications
19.6. [102]ACPI on x86_64 and other architectures
20.
[103]CPU_FREQ reference
20.1. [104]CPU frequency managers
20.2. [105]CPU frequency drivers
20.3. [106]How do I
regulate my CPU frequency?
21. [107]Kernel configuration
reference
22. [108]Boot parameter reference
23. [109]Sysfs
entries reference
23.1. [110]Overview of /sys entries
23.2. [111]Power entries in /sys
23.3. [112]Hotpluggable
devices and /sys entries
23.4. [113]CPU power states
(C-States) and /sys entries
23.5. [114]CPU frequency
management and /sys entries
23.6. [115]ACPI namespace tree
and /sys
24. [116]Proc entries reference
24.1.
[117]Overview of /proc entries
24.2. [118]Wake on RTC alarm
entry
24.3. [119]ACPI info entry
24.4. [120]DSDT
entry
24.5. [121]FADT entry
24.6. [122]Event queue
for acpid
24.7. [123]Embedded Controller entry
24.8. [124]Battery info
24.9. [125]Button entries
24.10. [126]Fan control
24.11. [127]Power resources
24.12. [128]CPU entries
24.13. [129]Sleep (deprecated)
24.14. [130]Thermal zone info
24.15. [131]Video adapter and
display entries
24.16. [132]Wake capabilities
25.
[133]Modified acpixtract
1. About this document
1.1.
Introduction
ACPI, which stands for Advanced Configuration and
Power Interface, is the
successor to APM (Advanced Power
Management). The specification provides for
many functions besides
power management, such as thermal management and
plug-and-play
events. This document covers those functions supported by
Linux
to-date. This document describes how to compile, install, and use the
ACPI driver for Linux and its associated applications.
I test
ACPI on a 32-bit x86 system, so this document is biased towards that
hardware. In particular, I do not discuss the ARM or x86_64
implementations
at all, SMP systems, nor ACPI on embedded systems.
For information on those
topics, see the links in [134]ACPI on
other architectures.
The current Linux kernel is 2.6.14-rc4.
This document covers configuration,
installation, patches and
problems for2.6.14-rc3 except for swsusp3, which
has been tested
only for 2.6.14-rc4. Some options or capabilities discussed
here
may not be available in earlier 2.6 or 2.5 series kernels. For
information about the (early) 2.4 kernel series, please check the
previous
EXTREMELY old version of this document, at
[135]~ariel/acpi/acpi_howto-01e.txt.
The current version of this document can always be found at
[136]~ariel/acpi/acpi_howto.html. You can also
find
other formats of this document at
[137]~ariel/acpi/.
_________________________________________________________________
1.2.
Copyright and License
This document, ACPI HOWTO, is
copyrighted (c) 2005 by Ariel T. Glenn.
Permission is granted to
copy, distribute and/or modify this document under
the terms of
the GNU Free Documentation License, Version 1.2, or any later
version published by the Free Software Foundation; with no Invariant
Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A
copy of
the license is available at
[138]
Linux is a
registered trademark of Linus Torvalds.
_________________________________________________________________
1.3.
Disclaimer
This document is provided ``AS IS'', with no
express or implied warranties.
No liability for the contents of
this document can be accepted. There may be
errors and
inaccuracies that could be damaging to your system. The author(s)
do not take any responsibility; use the concepts, examples and
information
at your own risk.
All copyrights are held
by their by their respective owners, unless
specifically noted
otherwise. Use of a term in this document should not be
regarded
as affecting the validity of any trademark or service mark. Naming
of particular products or brands should not be seen as endorsements.
_________________________________________________________________
1.4.
Credits/Contributors
I've been paying great attention to the
postings of Len Brown, Matthew
Garrett, Pavel Machek, Jon Smirl,
Li-Ta Lo, and Carl-Daniel Hailfinger. Dave
Jones' posts got me
through swsusp with swap on LVM on Fedora. Emma Jane
Hogbin nagged
me last year to get back to work on this stuff so I finally
did.
The City of Oakland kindly provided money for this laptop (lawsuit
settlement, that's another story). Greg Michalec is loaning me hardware
to
test suspend on ATI Radeon hardware. My housemates endured
long days of
obscure rambling about these topics. Thanks to
everyone.
_________________________________________________________________
1.5.
Feedback
Please send suggestions, complaints or comments
about this document to
ariel@columbia.edu. Please do NOT send me
bug reports about the driver; see
[139]Submitting useful bug
reports for more information on reporting ACPI
bugs.
_________________________________________________________________
1.6.
[FIXME]s
This document is a work in progress. Since it's been
4 years since I updated
this, there has been a lot of catching up
to do. I have left some sections
blank and they'll get filled in
Real Soon Now. Other sections are marked
with the warning [FIXME]
which tells me I have more work to do on that
section, and it
tells you that you should be extra careful when using
information
from that section. Thanks for your patience.
* I heard
rumors that the earlier nVidia X drivers, version .6xxx, may
suspend to RAM properly where the .7xxx series does not. I need to test
this.
* I have not worked with the Radeon patches, though a
friend of mine has
generously offered to let me borrow his
hardware to do some testing.
* If there are utilities for
suspend to RAM/disk or additional notes on
suspend on lid
close, I should add them, or remove those sections.
* Some
kernel CONFIG options have yet to be documented, and explanations
of a few of the boot parameters are incomplete.
* I need to add
pointers to information for ACPI on other architectures,
especially 64-bit platforms. First, there needs to be some information.
*sigh*
* The description of the /proc interface for the video
driver is almost
nonexistent.
* There should be more
examples of acpid event handling scripts.
* Clean up and fill
out documentation of how to trigger debugging for
select
pieces of acpi/suspend/hotkeys drivers.
* Write up polling
method for hotkeys driver.
* Document how to do suspend to disk
with raid. [How can I do this without
testing?]
* Fill
out the comparison for the various suspend to disk patchsets.
*
Detail more steps for debugging when suspend to disk doesn't work.
* Test and document suspend to file with swsusp2.
_________________________________________________________________
2.
Overview of ACPI
2.1. What is power management?
Power
management is a catch-all term for functionality that lets you
conserve power or use power resources for your computer more
efficiently.
For example, you may wish to reduce the brightness of
your LCD panel when
you're running your laptop off of batteries,
or you may want your CPU to run
in a lower power state if it's
idle, or you may want the system to hibernate
after 20 minutes if
you haven't been typing. All of these are examples of
power
management.
These days, power management includes support for
things like automated
system wakeup at a given time, switching
video displays, and monitoring fan
speed or chipset temperature.
Eventually it will probably grow to replace
the desktop OS. (Just
kidding...)
_________________________________________________________________
2.2.
What is ACPI?
ACPI, or Advanced Configuration and Power
Interface, is a set of
specifications for power management
functions of devices and the OS
interface to them. It consists of
descriptions of power specifications for
classes of devices
that describe which power states and what other
functionality a
class of devices must support, the definition of AML, an
interpreted language for describing these various functions, and a
description of how the OS calls these functions and in what context.
You may want ACPI if you are running a laptop and power conservation is
a
big concern, or if you want to put your desktop system to sleep
during
inactive periods, or if you want to monitor the
temperature of various
chipsets and to increase or decrease
fan speed depending on those
temperatures. You may want it so that
you can shut your laptop lid, take
your laptop to work, and open
it up again, ready to go at the touch of the
power button. And
your computer vendor may expect you to be using ACPI so
that the
OS will take appropriate action if the CPU or other chipsets get
too hot.
But I prefer to think of ACPI not as an optional
add-on component but as an
integral part of your system; in
today's world, where we are all conscious
of our energy use and we
don't think twice about turing off the light switch
when we leave
a room, enabling basic ACPI functionality is common sense.
In
very specific cases you may be required to enable ACPI for your system
to
function properly. 64-bit Itanium platforms require this; you
won't get a
choice in the kernel configuration menu to choose it
or not, it will just be
done for you. NUMA-enabled systems often
require it, and systems with new
Intel processors that support
hyperthreading require it because they use
ACPI tables for virtual
processor discovery.
_________________________________________________________________
2.3.
What is the difference between ACPI and APM?
APM, or Advanced
Power Management, is the predecessor to ACPI. It required
the
BIOS to handle all power management. Devices were put into lower power
states based on device activity timeouts. Only standby and hibernate
system
sleep states were supported. Some power management features
such as reducing
power usage of various devices when switching
from ac adapter to battery
were not implemented because this would
have required building support for
more power states and for
various power usage policies directly into the
BIOS. Adoption
of the ACPI standard started in 1997 when developers
understood
that putting most of the code in the OS would allow for more
features and greater flexibility. Version 3.0, the current ACPI
specification, was released in 2004.
The Linux APM driver is
very stable. It supports standby and hibernation,
but some newer
systems may not have support for APM in the BIOS at all.
Although
APM support in the kernel is very mature, patches still come in
once in a while. ACPI, by contrast, is under furious development. A
feature
may be broken in one release, work in the next, and
disappear completely in
the next. This is no joke. As I type
this, the latest FC4 kernel
(2.6.12-1.1447_FC4) has suddenly
made the /proc/acpi/button directory
disappear; acpid relies on
this to do the right thing (TM) when you close or
open your
laptop, or press the power button on resume. It was there in the
previous version; an overaggressive patch in 2.6.13-rc5 made it go away.
_________________________________________________________________
2.4.
What ACPI capabilities are supported under Linux?
As of
kernel 2.6.13, you can do the following (if you are lucky):
*
Suspend to RAM (S3 power state)
* Suspend to disk (S4 power
state)
* Enter standby (S1 power state)
* monitor your
battery and set an action to take on low charge
* monitor CPU
temperature and set actions to take when it gets too hot
*
monitor CPU speed, throttle your CPU, and put your CPU into different
power states
* monitor and turn on or off your fan
*
change your video display brightness, or enable an external video
display
* Set an action to take when you close your laptop
* Set an action to take when you press the power or sleep button
* Set your system to wake on a certain event
* And much more to
come!
Not all of these may work depending on what your
particular hardware/BIOS
setup supports and on the state of linux
support for that hardware.
_________________________________________________________________
3.
Hardware requirements
3.1. What hardware is supported?
Older systems have only APM support. In general, if you are working
with
hardware that is older than 1997, it will not have ACPI
support, and if it's
older than 2000, it will have only limited
support.
Support for modern ATI and nVidia video chipsets is
spotty under Linux.
Older video chipsets tend to have better
support. Cards based on the ATI
Radeon have support with
workarounds. This is very dependent on the version
of X you happen
to be using, and on the version of any X proprietary driver
as
well. [FIXME should test with earlier .6xxx nVidia to see if suspend
works, just for shits and grins]
For comprehensive lists
of laptops, their configuration, and their
functionality under
ACPI in Linux, see [140]ACPI on Linux laptops.
_________________________________________________________________
3.2.
What devices are supported?
Suspend/resume for SATA devices
is not working well yet. Jens Axboe has a
patch that will help for
some users; see the [141]SATA driver section for
more.
Brightness controls for LCD panels is sometimes not controllable by
ACPI;
often, the vendor uses some proprietary method, having the
BIOS adjust
brightness directly when certain hotkeys are pressed.
In this case you are
liable to see odd messages in your log like
these:
kernel: atkbd.c: Unknown key pressed (translated set
2, code 0x85 on is
a0060/serio0).
kernel: atkbd.c: Use
'setkeycodes e005
' to make it known.
Various
ethernet cards have problems, but there are patches. See the
[142]Ethernet cards section for more.
ATI Radeon cards usually
need help for suspend to RAM. See the [143]RadeonFB
patches
section for more. [FIXME and see if this helps X].
See also
the note above about supported hardware for information about other
video devices.
_________________________________________________________________
3.3.
Which BIOSes are supported?
Any BIOS that claims to support
ACPI can be used under Linux. In practice,
BIOSes older than 2001
that claim to have ACPI support are often broken.
Current BIOSes
are often broken too because they have broken DSDT tables or
missing ECDT tables.
If your DSDT is buggy, in the best case,
Linux ACPI functionality will be
enabled but some functions will
not work; in the worst case, your system may
freeze. Fortunately,
there is often a workaround available. See [144]DSDT
editing for
more information.
If your ECDT is missing, there's a boot
parameter, acpi_fake_ecdt, which can
help you. See [145]Boot
parameters reference for more information.
Some BIOSes are
known to be broken and they are included in a blacklist in
the
ACPI driver. Systems with those BIOSes at this writing are:
*
Compaq Presario 1700
* Sony FX120, FX140, FX150M
*
Compaq Presario 800, Insyde BIOS
* IBM 600E
* all
systems with ASUS P2B-S BIOS
_________________________________________________________________
3.4.
How can I tell if my BIOS supports ACPI?
The most reliable
way to tell is to boot with an ACPI-enabled kernel and
look for
ACPI messages in the log. You should see at least
kernel:
ACPI: Interpreter enabled
and messages like this if you have
PCI slots:
kernel: ACPI: PCI Interrupt 0000:00:1d.7[A]
-> Link [LNKA] -> GSI 11 (l
evel, low) -> IRQ 11
If you see messages like this:
ACPI: System description
tables not found
ACPI-0084: *** Error: acpi_load_tables:
Could not get RSDP, AE_NOT_FOUN
D
ACPI-0134: *** Error:
acpi_load_tables: Could not load tables: AE_NOT_F
OUND
ACPI: Unable to load the System Description Tables
then your
BIOS does *not* have ACPI support.
If you want other ways to
check your system, you can look at your BIOS
settings; many
systems have ACPI-related options in their BIOS menus, though
not
all. For example, the Dell XPS Gen 2, while fully ACPI-compliant, has no
mention of ACPI in the BIOS settings at all.
You can also run
acpidump, which is packaged with most distributions. To run
it,
be root and at the command prompt, type acpidump.
If your
system is ACPI-compliant, acpidump should print out a long list of
tables and their contents, including the RSDT and the DSDT. If you
don't see
a line something like
DSDT @ [some hex
address here]
you may have a problem. If acpidump produces no
output, it probably has
failed to find any tables. Check the exit
code; if it's 0x0005 then you
(probably) don't have ACPI support
at all.
If you want to look through memory yourself, and you
have 32-bit hardware
which is not EISA/MCA based, you could try
looking for "RSD PTR" in 0e0000h
through 0fffffh by grepping it
out of /dev/mem, like this:
# dd if=/dev/mem of=blot bs=64K
skip=14 count=2
# od -c -A x blot | grep 'R S D'
01c9b0 R S D P T R 312 D E L L \0
If you see output like this, you know you have the root table stricture
for
ACPI, which means that you have at least some degree of
support.
Note that none of these methods guarantee that the
BIOS support for ACPI is
bug free, just that it exists.
_________________________________________________________________
3.5.
When will my (unsupported) laptop be supported?
If the
problem is related to the video card, and you're using a proprietary
driver, the outlook is not good. It depends however on your particular
card
and BIOS. If posting your video card after resume helps your
problem, then
eventually that will be fixed because sooner or
later that code will make it
into X or into the kernel. It's also
possible that your video card vendor
may provide X drivers that do
the proper card reinitialization at some
point.
If the
problem is related to hotkey support, some laptops have specific
hotkey drivers, but a generic hotkey driver is available which you
should
check out as well. See the [146]Kernel configuration
reference for the
CONFIG_ACPI_HOTKEY option.
Detailed
bug reports are extremely helpful, as are volunteers to do testing
and debugging on their hardware. See [147]Debugging tips to get
started.
_________________________________________________________________
4.
Software requirements
4.1. Which kernels are supported?
All Linux 2.6 kernels and the current 2.4 series have ACPI support out
of
the box. If you are running one of the 2.2 series, you are out
of luck. Not
all new features from 2.6 are backported into the 2.4
series kernels. Your
favorite distribution probably has ACPI
support turned on by default.
Checked for: Fedora Core x; Suse
9.x; Debian 3.x, Ubuntu, Gentoo.
If a feature doesn't work for
you in one kernel, try the next one, or even
an rc intermediate
release, because so much changes from one week to the
next.
For the very latest in ACPI support, however, you should build your own
kernel and look at the most recent ACPI patches, as there is much hard
work
being done on this subsystem. The most recent patches can be
found at
[148]ftp://ftp.kernel.org/pub/linux/kernel/peple/lenb/acpi/patches/release/.
_________________________________________________________________
4.2.
What are the latest acpi driver / supporting utilities and where can I
get
them?
Basic ACPI support is included in the linux
kernel. You need acpid if you
want to capture ACPI events and take
certain actions based on those events.
You do not need to use
acpid if you want to do suspend to RAM or suspend to
disk and you
are willing to run a script by hand or work directly with the
sysfs interface. If you want to be able to shut down cleanly by pressing
the
power button, you should use acpid; in addition, if you want
to hibernate or
suspend on laptop lid close, you need acpid. See
[149]the acpid event
handling daemon to learn how to build and use
it.
Here are some of the userspace utilities for ACPI power
management. You
don't have to use any of them to get ACPI
functioning, but they can be much
more convenient than accessing
/proc/acpi or sysfs directly. This is not
meant to be a
comprehensive list. However, if you know of an application
that is
currently maintained and that you think should be on this list,
[150]let me know.
* acpitool -- command line utility to get
battery/fan/temperature/cpu
information or to suspend to
RAM/disk, turn on/off fans, and control
wakeup capable devices
* battstat-applet-2, bbacpi, wmacpi -- battery monitoring
*
wmpower, yacpi -- battery, temperature and other monitoring
*
powersave, with front ends kpowersave, gkrellm-powersave, wmpowersave --
all purpose utility covering APM, ACPI and other power management
features
* xrg -- all purpose monitor that watches everything
from CPU activity and
battery status to the weather and stock
market data
*
_________________________________________________________________
4.3.
Are binary distributions available?
All major distributions
come with ACPI support built into the kernel by
default. Fedora
ships out of the box with acpid and battstat-applet-2,
Debian has
acpid and wmacpi, Suse has acpid and powersave, and Gentoo has
acpid and quite a number of monitoring/power management utilities. Check
your distribution's documentation to see what prepackaged options you
have.
_________________________________________________________________
5.
Compilation and installation
5.1. Prerequisites and kernel setup
To build your own kernel with ACPI support, you need the following:
Make sure that you're building with the appropriate version of gcc (at
this
writing, at least version 3.2).
Turn on these
configuration options for base ACPI support: CONFIG_PM,
CONFIG_ACPI and CONFIG_PNPACPI.
For ACPI control of some
basic devices, set these: CONFIG_ACPI_AC,
CONFIG_ACPI_BATTERY,CONFIG_ACPI_BUTTON,CONFIG_ACPI_VIDEO,CONFIG_ACPI_FAN,
CONFIG_ACPI_PROCESSOR, and CONFIG_ACPI_THERMAL.
For suspend
to RAM, set CONFIG_ACPI_SLEEP, and for suspend to disk, set
CONFIG_SOFTWARE_SUSPEND, and also supply the name of the partition
reserved
for writing suspend data to CONFIG_PM_STD_PARTITION.
NOTE: if you are
suspending from something other than a standard
swap partition, read the
[151]Suspend to disk section
because you may want to set
CONFIG_PM_STD_PARTITION to "".
For more details on these config options or for the other kernel
configuration options for ACPI, see the [152]Kernel configuration
reference.
_________________________________________________________________
5.2.
Useful BIOS settings
Most ACPI-capable BIOSes have settings
that the user can tweak for power
management. For example, recent
versions of the AMI BIOS have an entire
section for ACPI settings,
including ACPI-Aware OS, ACPI 2.0 compliance,
BIOS->AML ACPI
table, all of which should be enabled; Suspend to RAM
support,
and Repost video on S3 resume which may be useful if your video
doesn't come back after resume from suspend to RAM. Check your BIOS to
see
what power management features it offers you.
If you
see APM settings in your BIOS you can ignore those. As long as you
have ACPI built into your kernel and enabled, the APM settings will not
be
used.
_________________________________________________________________
5.3.
Boot parameters
You should not need to pass any special boot
parameters once ACPI is built
into the kernel. If you run into
problems, or you have special requirements,
check the [153]Boot
parameters reference for a comprehensive list.
_________________________________________________________________
6.
The acpid event handling daemon
6.1. What is acpid and where do I
get it?
Older versions of acpid used to act as an
intermediary between the kernel
and the BIOS, looking up hex
values that could be used to invoke certain
sleep types and
installing sleep methods; it also used to provide battery
information and it had the entire AML interpreter in it. But it didn't
support suspend to disk or suspend to RAM.
These days, the
entire interpreter for AML now lives in the kernel. I
stopped
maintaining this document shortly after that patch
[154]() got
accepted about 4 years ago. It singlehandedly added around 72000 lines
of
code to the kernel. One developer [fn1] is pretty sure that
ACPI was
designed by a bunch of monkeys on LSD, but if it had, it
would at least be
visually appealing. And this ain't.
OTOH, the acpid daemon has become much simpler. It now watches for all
acpi-generated events and allows the user to define the appropriate
action
to take on receiving those events.
Most
distributions come with acpid out of the box. If you want to build your
own, you'll find the latest version at
[155]
[fn1] See
[156]
_________________________________________________________________
6.2.
How do I build and install acpid?
Make yourself a build
directory and untar the file: zcat acpid-1.0.4.tar.gz
| tar xvfp -
cd into the directory: cd acpid-1.0.4
If you download the
tarball, edit the Makefile if you're using gcc 4.x:
change the
line CFLAGS = -Wall -Werror -g $(DEFS) to read CFLAGS = -Wall -g
$(DEFS) (This is fixed in cvs.)
build it: make install it:
make install This puts acpid in /usr/sbin and
acpi_listen in
/usr/bin It also installs the man pages.
These programs use
/proc/acpi/events (boo). When will they use /sys?
_________________________________________________________________
6.3.
How do I use acpid?
Linux sees ACPI events, in some cases
takes an action, and then writes a
description of the event to
/proc/acpi/events so that userspace applications
can take actions
as well. Acpid watches /proc/acpi/events and, for every
event
logged there, looks at its set of rules to see what action(s) to take.
These actions are specified by you, the user.
Acpid looks for
its rules by default in /etc/acpi/events at all files in
that
directory (no subdirectory walking though). Each file in there is
expected to contain rules that tell acpid what to do on each event.
Each file may have blank lines or comments starting with # Then you
must
include at least one line defining an event and one line
defining an action.
Here's an example:
# This is a
sample ACPID configuration
event=button/power.*
action=/sbin/shutdown -h now
That file ships with Fedora Core 4
and tells acpid to shut down when the
power button is pressed (so
you don't have to give the three-finger salute).
%e and %%
are special strings; if you use %e in the event description or in
the action description, the full text of the event as described in the
previous section will be substituted into the string, and if you use %%
in
either description, the character % will be substituted in. If
you use % in
any other combination, you'll get an error.
You can define multiple actions for the same event, but they won't
necessarily be processed in the order you list them in the file.
You can also put multiple event lines in one file and use the same
action
for all of them. [FIXME examples would be nice]
If you have acpid source from CVS or tarball, you can look at more
interesting examples such as the battery.sh script which is intended to
be
used from one of these rule files. It reacts on any battery
event, checks to
see whether the system is on AC or battery, and
sets or disables hard drive
spindown time appropriately. Note that
this script may not work for you out
of the box, as your AC
adapter may have a different name (mine is called
/proc/acpi/ac_adapter/AC); it's here as an example only.
On
FC4 you are expected to put all your fancy scripts into
/etc/acpi/actions
but nothing in the acpid code requires this. Put
them where you want.
_________________________________________________________________
6.4.
What events will acpid respond to?
It is not possible to
provide a comprehensive list, because the list of
events depends
on your vendor's hardware and their ACPI implementation.
However,
it is possible for you to figure out what events will be issued on
your hardware by looking at /sys/firmware/acpi and collecting some
information.
First, let's see what an event looks like. If
you are running acpid, and you
are running ACPI with any applet to
monitor battery status of control cpu
speed, you can look in
/var/log/acpid at events it has received. You may see
messages
like this:
completed event "processor CPU0 00000080 00000004"
received event "ac_adapter AC 00000080 00000001"
received
event "battery BAT0 00000080 00000001"
received event
"button/power PBTN 00000080 00000001"
Each event as logged
consists of the device class name, the bus id name, the
event
type, and the event data. Device class names are standardized, and you
can get the list by looking for all #defines of "CLASS" in the kernel
code
in drivers/acpi. My list is:
ac_adapter, battery,
button, container, embedded_controller, fan, Hotkey
(because the
asus driver got the word "hotkey"), lid, memory, pci_bridge,
pci_irq_routing, power, power_resource, processor, sleep, system_bus,
system, thermal_zone, video
Note that some of these are
subclasses; power, sleep and lid are subclasses
of button, and
they'll get written as button/lid, button/power and
button/sleep
in the log.
Bus IDs are not standardized; they are defined in a
vendor's implementation.
Fortunately, the names vendors use are
similar and usually recognizable.
You can find out which Bus
IDs your vendor is using on your current hardware
by looking in
/sys/firmware/acpi/namespace/ACPI/. My system shows
ls
/sys/firmware/acpi/namespace/ACPI/
CPU0 CPU1 _SB _TZ
ls /sys/firmware/acpi/namespace/ACPI/_SB
AC BAT0 LID MB1
PBTN PCI0 SBTN
ls /sys/firmware/acpi/namespace/ACPI/_SB/PCI0/
AGP AUD IDE0 ISAB LNKA LNKB LNKC LNKD LNKE LNKF LNKH MB2
MB3
MODM PCIE USB0 USB1 USB2 USB3 USB4
You may
decide you don't need to know what the event type is; for example,
if you get a battery event, you might look at
/proc/acpi/battery/BAT0/info
(or BAT1/state, or whatever your
battery device is called), check the
remaining capacity and take
any appropriate actions.
However, there is a list of event
types in the ACPI specification. Here's
the summary:
For
all devices, 0 = bus check (time to rescan the bus); 2 = device removed
or added; 3 = device awakened; 4 = device eject, 5 = device removed or
added
("device check light", don't ask me what the difference
between this and 2
is); and some other events that you probably
won't care about as a user. See
page 142 of the specification if
you want the rest.
For specific devices:
Battery:
0x80 = battery status changed, 0x81 = battery information has
changed (i.e. you have a different battery in there now); 0x82 = check
battery maintenance flags.
Power source: 0x80 = power source
status changed. (Think AC adapter.)
Thermal zone: 0x80 =
thermal zone temperature changed; 0x81 = thermal zone
trip points
changed; 0x82 = thermal zone device lists changed; 0x83 = values
in thermal relationship table changed
Power button: 0x80 =
power button pressed. Warning: If the power button is
pressed with
the system in S1 through S4, you will not see this event;
instead
you will see a Device Wake (0x02)!
Sleep button: 0x80 = sleep
button pressed. Warning: If the sleep button is
pressed with the
system in S1 through S4, you will not see this event;
instead you
will see a Device Wake (0x02)!
Lid: 0x80 = Lid status changed
(either open or closed).
Processor: 0x80 = number of
supported processor performance states (P
states) has changed;
0x81 = number or type of supported power states (C
states) has
changed; 0x82 = number of supported throttling states has
changed.
video (part 1): 0x80 = state of one of the displays attached to the
graphics
adapter has been toggled; 0x81 = re-enumerate all devices
on the adapter
(i.e. a device has been added or removed); 0x82 =
cycle display output (next
display activated and if the last one
was active then the first one now is);
0x83 = next display
activated; 0x84 = previous display activated. Note: for
these
events, when a new display is activated, Linux deactivates the
previously active one. If you want more than one display to be active,
you
should activate them by using the /proc/acpi/video/VID/*/state
interface.
See [157]Proc entries reference for the /proc entries.
Also, I'm unsure if
cycling the display output really should put
you back to the first device if
you are at the end of the list; at
least, Linux doesn't appear to do this,
from a quick scan of the
code.
video (part 2): 0x85 = display brightness increased one
level and if it was
at max, it got set to min level; 0x86 =
display brightness increased one
level and if it was at max, it
stayed there; 0x87 = display brightness
decreased one level and if
it was at min, it stayed there; 0x88 = display
backlight turned
off; 0x89 = display off WARNING: these values are right out
of the
ACPI 3.0 spec. But they are not the values Linux uses! It uses: 0x82,
0x83, 0x84, 0x85, 0x86 for each of these things in order. Uh oh... I
don't
have (ACPI) brightness control support, so I can't test this
to see what
should happen. Anybody?
Some events that
Linux passes on are not defined in the spec; that is, I
can't find
a table with numbers for these. I got the values by looking for
invocations of acpi_bus_generate_event() in the kernel acpi driver code,
and
checking the event passed in that function.
thermal
zone: 0xf0 = critical temperature trip point is being passed which
requires immediate shutdown; at this point Linux will shut down by
calling
/sbin/poweroff. You don't really have much time to process
this event. :-)
0xf1 = critical temperature trip point is being
passed which requires the OS
to put the system into S4 (hibernate)
if that state is supported. The Linux
kernel does not yet do
this. It has a comment placeholder where the code
ought to go.
If you use the generic hotkey driver (CONFIG_ACPI_HOTKEY), then when
you
press an authorized hotkey, you'll get an event sent to
/proc/acpi/events
for it. That list is described in [158]How do I
use the hotkey driver?
No, I'm not documenting the state data;
look it up your own darn self :-)
_________________________________________________________________
6.5.
How can I keep track of what acpid thinks it's doing?
Acpid
logs all of its activity to /var/log/acpid by default. Check your init
scripts to see where your distribution directs its logging.
You can also run acpi_listen. This command will connect to acpid and
write
every event that acpid sees to stdout, in exactly the format
the event
appears in /var/log/acpid, but without the extra
commentary.
_________________________________________________________________
6.6.
Where can I find other cool acpid scripts?
A few nice
Thinkpad scripts can be found at
[159]
Unfortunately, scripts are very dependent on your particular hardware
configuration.
Some folks have put up acpid scripts on
their pages describing the
installation of some distribution on
their laptop. Check [160]these
resources for more information.
_________________________________________________________________
7.
CPU management under ACPI
7.1. CPU management overview
ACPI gives you unprecedented control over your CPU's power consumption.
You
can control power usage in three different ways: setting
idling power
states, changing cpu frequency, and throttling the
CPU.
_________________________________________________________________
7.2.
CPU idle power states
First, the CPU can enter different idle
power states, C1 through Cn (usually
C1 through C4). If a
processor is in state C0, it is working normally; in
any other
state, it is idle (doing no work). Lower power states use less
power but the CPU will take longer to transition to a higher power
state. So
if your CPU is in C4 it will use less power than in C3
but it will take
longer to come out of idle than from C3.
You don't have to do anything to make the CPU go into the appropriate
idle
state; the kernel will place the CPU into a lower power state
automatically
when it is not busy. However, you do need to build
this capacity into the
kernel by enabling CONFIG_ACPI_PROCESSOR.
See the [161]kernel configuration
reference for the CONFIG
options.
You can look at the /proc/acpi/processor/power file
to see how long your CPU
spends in each state; see [162]Proc
entries reference for more on this file.
You can also look at
/sys/module/processor/parameters/max_cstate to see what
the lowest
power state the kernel will give you is; see [163]Sysfs entries
reference for more on that.
And you can adjust max_cstate by
using the processor.max_cstate boot
parameter. In some cases
machines that enter C3 or C4 produce a loud whine,
and you may
want to limit your system to C1 and C2. In some cases you may
want
your system to enter C3 or C4 but it's been blacklisted by the kernel
and limited to C2; you can use this same parameter to override the
blacklist. See [164]Boot parameter reference for details.
_________________________________________________________________
7.3.
CPU frequency management
Second, you can also run the CPU at
lower frequencies when it isn't doing so
much work. If you're
spending most of your time typing text instead of
compiling, this
can be very useful for power savings. In ACPI lingo, the CPU
enters various P-States, P0 through Pn, where at P0, the CPU is running
at
its highest frequency and at Pn it runs at a lower frequency
the greater the
value of n. These performance states are only
valid when the CPU is in power
state C0; the rest of the time
the CPU is in some idle state and so
adjusting its clock frequency
doesn't make any sense.
To benefit from this, you'll need to
enable CPU frequency control by setting
CONFIG_CPU_FREQ. Then you
can choose which of several performance managers
to build in;
these adjust the frequency based on different criteria. Then
you
can choose which hardware-level driver to build in. Only certain of
these drivers support ACPI P-States; the rest use a proprietary method
of
regulating CPU frequency and are not discussed further in this
document.
Further, of those that use the designated P-States, only
the ACPI P-States
driver (CONFIG_X86_ACPI_CPUFREQ) actually
notifies the ACPI subsystem of
P-State changes. If you think this
is confusing, you're right.
After your kernel is set up, you
can either use one of several userspace
applications to
automatically set your CPU to a lower frequency depending on
the
load, or you can use an applet that lets you set the frequency manually
as you desire, or you can use one of the performance managers that
adjusts
frequency for you in kernel space. For all the details,
see [165]CPU_FREQ
reference.
_________________________________________________________________
7.4.
CPU throttling
Third, you can throttle your CPU. This means
that you force the cpu to be
idle a fixed percentage of its cycles
per second. Throttling states are
called T1 through Tn, where in
T1 the CPU has no forced idle cycles, and the
percentage goes up
the greater n is. For example, on my system, T4 forces
the CPU to
be idle for half of the cycles.
This is different from
changing the frequency, which makes the cpu have
fewer cycles per
second, and it's different from running in a C state other
than
C1, because those are states where the CPU is idle for all cycles.
If you have a certain amount of work to get done, then throttling the
CPU
will cause the work to take longer to get done. However, if
temperature is a
concern, then this will keep your CPU running
cooler.
Note that this does not reduce voltage, and since all
tasks will take longer
(since the CPU is forced idle part of the
time), you actually use more power
to get any given task done.
This is in contrast to CPU frequency management;
when the CPU
frequency is lowered, voltage is lowered too, and any given
task
should draw less power unless it requires the CPU to run full out for
the duration of the task.
You can check which throttling
states are supported by your CPU by looking
at
/proc/acpi/processor/CPU*/throttling. This file will also show you what
percentage of idle time each state enforces. You can set the current
throttling state for your CPU by writing the state number to
/proc/acpi/processor/CPU*/throttling. Read it back to make sure the
change
works; if it doesn't, you may have a bug in your DSDT or
elsewhere.
Note that throttling states only work when the CPU
is in the power state C0.
But they work for any performance state
(P-state); this means that no matter
what frequency the CPU is
running at, you can still do throttling. For
information on how to
do this, see [166]Thermal management.
_________________________________________________________________
8.
Thermal management
8.1. Overview of thermal management
ACPI provides several means for monitoring and controlling system
temperature. Via thermal zones, you can adjust the system cooling mode
when
it's too hot, you can turn on and off fans when you
reach certain
temperatures, and you can throttle your CPU when it
gets too hot, taking
into account the performance state it's
running in. Not all platforms
support all of these features, but
the ACPI 3.0 specification provides all
of these mechanisms.
_________________________________________________________________
8.2.
What are thermal zones?
If your vendor's implementation of
ACPI supports thermal management, you'll
have one or more
thermal zones, which you can monitor by checking
/proc/acpi/thermal_zone for these devices. They'll be called something
like
THM or THRM0.
I haven't seen a system with multiple
thermal zones. Typically a system has
one big thermal zone which
includes the entire interior region of the case.
Practically
speaking, it must be connected to a sensor somewhere, probably
by
the CPU.
Linux should poll the temperature every so many
seconds. In practice,
however, Linux tries to figure out how often
to poll by invoking the _TZP
method, which many vendors don't
provide. When that fails, Linux disables
polling altogether.
Fortunately, you can enable it by echoing a number to
the file,
for example, echo 30 >
/proc/acpi/thermal_zone/*/polling_frequency, to have Linux check the
temperature every 30 seconds.
You can monitor the temperature
for each thermal zone yourself by reading
the file
/proc/acpi/thermal_zone/*/temperature.
_________________________________________________________________
8.3.
What are cooling modes and how do I change them?
A cooling
mode is a description of how your system is cooled in a certain
temperature range. Your cooling mode can be critical, passive, or
active.
Active cooling means that a fan or other cooling device
can be turned on
when the temperature passes a critical point.
Passive cooling means that
devices can be put into a lower power
state when the temperature is too hot.
Critical cooling means that
when the temperature passes one trip point, the
so-called "hot
point", the OS will transition into S4 (suspend to disk) if
possible, and if the temperature passes a second trip point, called the
"critical point", the OS will shut down the system.
If your
platform supports it, Linux will set the cooling mode to active by
default. If this isn't successful, but both active and passive modes
are
supported, then the cooling mode which supports the lowest
trip point is the
one in use. If only one of passive or active
cooling modes is supported,
Linux will use that. Failing that, it
will fall back to critical cooling
mode, which must be supported
by your vendor.
Some platforms allow you to change the cooling
mode. You can do this by
echoing 1 to
/proc/acpi/thermal_zone/*/cooling_mode to set passive cooling,
or
0 to /proc/acpi/thermal_zone/*/cooling_mode to set active cooling.
Critical cooling will always be active, in case your system heats up so
much
that drastic measures must be taken, even with fan use or
power reduction.
_________________________________________________________________
8.4.
What are trip points and how do I set them?
Trip points are
set temperatures that, when the system temperature reaches
them,
trigger some sort of action. Typically this can be a change in cooling
mode, or something more drastic. The critical cooling mode has two
predefined trip points. If the system reaches the first one, called the
"hot
point", Linux will try to put the system into S4 (suspend
to disk) if
possible, and if the temperature passes the second
one, called the "critical
point", Linux will call /sbin/shutdown
-h now.
You can define multiple trip points each with their
own cooling policy. If
you do, they'll show up in
/proc/acpi/thermal_zone/*/trip_points like this:
critical
(S5): 100 C
passive: 97 C: tc1=4 tc2=3 tsp=40
devices=0xcf6b6d80
You can set critical, hot, passive, and up
to 9 active trip points. Here's
how you do it: echo a string of
numbers to
/proc/acpi/thermal_zone/*/trip_points separated by a
colon. These numbers
are the various trip points in Celsius. NOT
IN Fahrenheit! So you *can* echo
99:80:35:75:60:55:50:45 >
/proc/acpi/thermal_zone/*/trip_points to set the
critical trip
point at 99C, the "too hot, suspend now" trip point at 80C,
the
passive trip point at 35C, the first active trip point at 75C, the next
one at 60C, and so on through the fifth active trip point at 45C, but
in
practice that's a lot of trip points. You probably only need
one or two;
after all, how many extra fans do you have? However,
Linux expects to see at
least 5 values, and if it doesn't see them
it throws an error and refuses to
process the change. So even if
your system only does passive cooling, you
must supply values for
active[0] and active[1]. Just set them to 0 if they
don't make
sense for your platform.
Unfortunately, if you write values to
trip_points (at least 5) and these
other cooling methods are not
supported, Linux will not inform you about it.
It will silently
accept the values and move on. On my system I can't even
reset
the lone critical trip point permitted me; but no errors are
generated; the only way I can tell is to read the trip_points file again
and
see that it hasn't changed.
_________________________________________________________________
8.5.
What are throttling/performance state limits and how do I use them?
These limits set the highest (highest frequency) P-State, and highest
(least
throttling) T-state your platform is permitted to use
under certain
circumstances, where P0 is a higher P-State than P1,
and T0 is a higher
T-state than T1. Sorry for the lousy
terminology.
You can see what the current throttling/p-state
limit is, by looking at the
file /proc/acpi/processor/limit. Look
at the active limit, which will show a
performance state, like P0,
and then a throttling state, like T0.
To set a limit, write
two numbers separated by a colon, like "0:0" into
limit. The first
number is the processor performance state, and the next
number is
the processor throttling state. This will set the user limit,
which you also see when you read that file. The active limit is chosen
as
the maximum of the user and thermal limit T-state numbers; i.e.
if the user
limit is T2 and the thermal limit is T3 then the
active limit will be T3.
Unfortunately, Linux does not seem to
use the first number for anything. It
always uses the value of 0
to update its internal copy of what it thinks the
P-State is for
display in the limit file. Maybe that's ok, since it never
actually sets the P-State from that value :-(
Warning,
esoterica: Only the ACPI P-States cpufreq driver updates the CPU's
P-States. This file could either show the actual P-State (and update it
on
demand) for that one driver, or it could map frequency changes
from all
drivers into P-States by name, and reflect the change by
changing frequency
according to the registered cpufreq driver.
Right now it just leaves the Px
value around in the limits file to
be confusing to the user, the worst of
both worlds.
In
any case, the second value does get stuffed into the user limit thermal
value, and you can verify that by reading the file. It takes effect
immediately. Note that the user limit can never be a higher (less
throttling) state than the thermal limit; for example, if the thermal
limit
is T1, then the user limit cannot be T0.
_________________________________________________________________
9.
ACPI generic hotkey driver
9.1. What is the generic hotkey
driver and how do I use it?
The generic hotkey driver allows
you to make those nifty hotkeys on your
laptop work. The concept
is simple; your laptop has a hotkey that Linux
doesn't understand
and that has no effect. You expect it to actually set the
brightness of your LCD to max, for example. So, you define a function
that
includes the ACPI event number generated by your hotkey, the
hotkey driver
event number that corresponds to the function you
want the key to do (here,
increase brightness), information
required to find the right video device,
and the ACPI method name
for increasing brightness. Once the function is set
up, any time
you press the hotkey, an event will be generated that acpid can
pick up, and once you define the right rule for acpid, you'll have your
hotkey working.
_________________________________________________________________
9.2.
How can I tell if my laptop supports the generic hotkey driver?
This does not work for all laptops; your laptop must generate an ACPI
event
when you press the particular hotkey you want to use. This
means that in
your DSDT, you will have something like
\_SB.PCI0.LPC.EC.HKEY.BTIN () (IBM
laptops), or Name (_HID,
"ATK0100") (ASUS), or Device (HKEY) (Panasonic).
If you want
to know if your hotkeys generate ACPI events, one way you may
test
this is to turn on debugging (CONFIG_ACPI_DEBUG = y) in your kernel,
boot up, echo '0xffffffff' to both /proc/acpi/debug_level and
/proc/acpi/debug_layer, and then press a hotkey. Just one! Once! This
will
either generate a lot of error messages in your log, or none
at all. If it
generates none, you are out of luck. Otherwise, you
should be able to use
this driver. [FIXME see which parts of the
debug layer we can minimally turn
on to get useful messages.]
_________________________________________________________________
9.3.
How can I get the ACPI event number for my hotkey?
You can
try just pressing the key and see if anything shows up in
/var/log/messages. If not, you'll have to resort to the method described
above, i.e. build in ACPI debugging, turn on all debugging bits, and
then
slog through the log.
The event number that your
hotkey generates can then be retrieved by looking
for lines in
your log like "ev_queue_notify_reques: Dispatching Notify(80)".
_________________________________________________________________
9.4.
How do I set up a hotkey function?
Let's take our earlier
example. Say your laptop has a hotkey that should set
the
brightness of your LCD to max. So, you define a function that includes
the event number generated by your hotkey (which you must determine by
looking at log output after pressing the hotkey), the appropriate
hotkey
driver event number, in this case 0x86, the ACPI bus name
on your platform,
the ACPI full path name for your LCD, and the
AML method you are going to
call, which in this case is _BCM, the
AML method to control the brightness
level.
On my
system, if Dell actually had hotkeys implemented through ACPI, which
it doesn't, I'd do the following:
echo
'0:_SB::_SB.PCI0.AGP.VID.LCD:_BCM:128:136' > /proc/acpi/hotkey/eve
nt_config
I've used a made-up value for the event number generated by pressing
the
hotkey, since Dell hotkeys don't generate ACPI events, but the
rest is
correct for my platform. I could then verify that the
setup worked by
looking in the log for errors and by reading
/proc/acpi/hotkey/event_config,
which would give me
_SB_:LDD_:_DSS:128:136
Let's look at that in a little more
detail. In the example above, we have 7
arguments, which you
must always provide to add a new key. The first
argument must be 0
which indicates that this is a new key definition. The
second
argument is the name of the bus on which your device sits that you're
going to affect; the LCD panel on my system is on the _SB bus. The
third
argument must be omitted for event-based key definitions.
The fourth
argument is the full ACPI namespace path name of the
device, and the fifth
argument is the AML method you are going to
call. The sixth argument is the
event number that your key press
sends to the ACPI driver, and the seventh
argument is the hotkey
driver event number which the driver will use to look
up the event
in its tables. For the seventh argument, you can use any hotkey
event number you like (as long as it's known to the driver), but you may
kick yourself later when you have to read your script and understand
what it
does.
You can also set up keys to use a polling
method; I'll cover that in a
future version of this document.
[FIXME]
Fun fact: you don't have to map the hotkey to a method
that has anything to
do with the intended function of the hotkey,
or with the intended meaning of
the event number you chose from
the hotkey driver event list. So you could
map your wireless
activation hotkey to turn of your fan via the _OFF control
method,
if your fan supports that control method. I'm not saying you should;
I'm just saying you *could*.
To remove the key
definition, just do echo '1:::::128:136' >
/proc/acpi/hotkey/event_config where the 128 should be replaced with the
actual ACPI event generated by the key press, and the 136 should be
replaced
with the hotkey driver event number you actually used.
To change the definition, just put the new definition to
/proc/acpi/hotkey/event_config but use '2' as the first argument, which
indicates that the key definition already exists and should be updated
with
the new values.
_________________________________________________________________
9.5.
What are the hotkey driver event numbers?
The list, grabbed
from hotkey.c, is
video (see video events above for more on
what these do):
* 0x80, cycle output device hotkey pressed;
* 0x81, output device status change hotkey pressed (maybe it
disconnects
one of the devices);
* 0x82, cycle display
output hotkey pressed;
* 0x83, activate next display output
hotkey pressed;
* 0x84, activate previous display output hotkey
pressed;
* 0x85, cycle display brightness hotkey pressed;
* 0x86, increase display brightness hotkey pressed;
* 0x87,
decrease display brightness hotkey pressed;
* 0x88, set display
brightness to zero hotkey pressed;
* 0x89, turn display off
hotkey pressed
sound (why are these here? they aren't ACPI
related):
* 0x8a, volume mute hotkey pressed;
*
0x8b, volume increase hotkey pressed;
* 0x8c, volume decrease
hotkey pressed
sleep states buttons:
* 0x8d,
Suspend to Ram hotkey pressed,
* 0x8e, Suspend to disk hotkey
pressed,
* 0x8f, Soft power off hotkey pressed
_________________________________________________________________
9.6.
What should acpid do after I press a hotkey?
Once the
definition is set up, if I pressed the hotkey, an event of type
"Hotkey Hotkey 0x00000086 0" would be generated, and acpid could pick it
up
and do the right thing with it. The right thing is
already almost
predefined: it should echo "136:1::100" >
/proc/acpi/action where 136 is the
event code that acpid was given
in /proc/acpi/events converted to decimal,
the "1" means it is
event based rather than poll-based, i.e. the event was
read from
/proc/acpi/events, the third missing argument is only needed for
poll-based hotkeys, and the 100 is the argument to _BCM to set the
brightness to the maximum level.
The trick is that most of
these methods actually don't do exactly what you
want the hotkey
to do. Here's a summary of the relevant AML methods from the
ACPI
spec.
_BCM controls brightness. Pass the number (percent of
100) to set the level
to. Supported brightness levels can be
retrieved by reading the file
/proc/acpi/video/VID/*/LCD/brightness (or CRT, or whatever device you
are
checking). That means that if you have a hotkey for increasing
brightness,
mapping it to this method will not be enough. You
should use a script that
gets the current brightness, checks the
supported levels, and sets the next
one. That script can use
/proc/acpi/action, but it will have to have figured
out the right
brightness level as the argument to _BCM first.
_DSS makes the
display active or inactive. Pass 0x80000000 to inactivate,
and
0x80000001 to activate. You can see the state of each device by reading
the file /proc/acpi/video/*/LCD/state (or CRT, or whatever device you
are
checking). That means that if you have a hotkey to switch
between CRT and
LCD, mapping it to this method will not be enough.
You should use a script
that gets the current active device,
inactivates it, and sets the other one
as active.
There
are no methods for sound control in ACPI; that's not really a power
management feature. In order to get the sound-related hotkeys to work,
you
may have to have acpid run alsamixer or some such to do the
right thing.
The sleep state hotkeys are another bit of a
kludge. What you want to do
here is to have acpid do any prep work
for the suspend or power off; for
suspend, you may have modules
you want to remove, and so on. Then you want
to actually do the
suspend by echoing the right state into /sys/power/state,
and
finally do the right thing on wakeup, by reinserting modules and so on.
For poweroff, you can have acpid call /sbin/shutdown -h now, or
whatever
other shutdown mechanism seems good to you. Once again,
these hotkeys must
be set up with placeholder bus names, device
paths, and AML method names;
these items are only there so that
the hotkey driver will register the key
definition and not throw
an error.
So what this means is that in all of these cases you
are going to use a
script to handle the event. There is perhaps
one exception: if you have a
hotkey that turns off the display, or
turns the brightness down to zero, you
can map that directly to
the appropriate method with a fixed argument. In
the rest of these
cases, you still have to pass a valid bus name, device
path, and
AML method name, so choose something harmless and then don't ever
use /proc/acpi/action with it. I recommend _SB for the bus name,
_SB.PBTN
(or whatever your power button is called) for the device
name, and _PSW for
the method name, since you won't need these for
anything else. This assumes
your power button supports _PSW; if
not you may have to look around in your
DSDT yourself for some
ideas.
_________________________________________________________________
9.7.
Where do I find ACPI bus names and device paths?
Bus names
are easy; see the discussion of bus names as part of events in
[167]How do I use acpid? Device paths are not easy, because device names
are
set by the vendor and vary from one platform to the next. You
can get valid
device paths for your system out of the ACPI
namespace by looking at
/sys/firmware/acpi/namespace/. Find the
device you're going to affect
somewhere in the directory tree, say
LCD, and grab the full name, starting
with _SB and ending in the
device name. You need to put a "." instead of a
"/" between
directory names, so that you get something like
_SB/PCI0/AGP/VID/LCD converted to _SB.PCI0.AGP.VID.LCD as the device
path.
Again, this is only useful in the rare case where you have a
hotkey that
does a fixed action (not increasing the brightness,
but setting it to
max/min; not switching the active display but
turning one off or on).
_________________________________________________________________
10.
Suspend to RAM
10.1. How do I suspend to RAM?
Suspend
to RAM is part of the kernel. Make sure you have ACPI enabled in the
BIOS and the kernel, and that you have the CONFIG_ACPI_SLEEP option
set.
It's a good idea to remove all usb devices and modules,
as well as any
firewire devices and modules. If your suspend works
well without them, try
adding them back in.
Then echo
mem > /sys/power/state You'll see some messages on the console
about suspension, ending with
hwsleep-0296 [08]
acpi_enter_sleep_state: Entering sleep state [S3]
Then your
system should go to sleep.
Pressing the power button should
bring the system back, starting with some
hard disk activity.
_________________________________________________________________
10.2.
My video isn't working; what now?
* Type an innocuous
command such as ls and press ; some folks
report
that their display comes back on the first key press.
* If your laptop supports display brightness adjustment, and that works
on
your system before suspend, try using that after suspend
and see if your
video comes back.
* See if switching
your video display from your internal LCD to an
external CRT
and back brings back your video. You can do this even if
you
don't have an external CRT hooked up. See [] on how to do this.
*
If none of those things work, see if your system responds to
keypresses.
Does pressing the Caps Lock key turn the Caps Lock
LED on? If not, wait
about 5 minutes, and try the same
activity again. Sometimes the kernel
has gone out to a short
snack instead of out to lunch. This works for
me.
* If
you have Caps Lock responsiveness, try suspension with networking
enabled, and see if your computer is pingable (again, wait 5 minutes if
there is no initial response).
* If it is, you might try again
with sshd and see if you can log into the
system. Then you can
try some vbetool tricks to muck with the display.
See
[168]Vbetool for vbetool usage and tricks.
* If you don't have
network access, see if typing sync gives you disk
activity. If
so, you can try the vbetool tricks mentioned above. Set up
a
script ahead of time so that you can minimize typing mistakes while
typing blind.
* If none of those things work, you can try a
few specialized boot
parameters: acpi=s3_sleep, acpi=s3_mode,
or pci=routeirq. See [169]Boot
parameters reference for more
information.
*
*
_________________________________________________________________
10.3.
What utilities are there that I can use for this?
[FIXME]
_________________________________________________________________
10.4.
How about suspend to RAM when I close my laptop?
[FIXME]
_________________________________________________________________
10.5.
My usb/pcmcia/other device doesn't work when the system resumes; what
can
I do?
Build usb support and the specific driver support
for those devices as
modules and write an acpid script that
removes these modules before
suspension and reinserts them
afterwards. Here's an example, adapted from
Gentoo's wiki page on
the Samsung X20 at
[170]
#!/bin/sh
if [ -e /tmp/lidclose ]
then
echo "[" `date` "] Wakeup from standby (lid opened)" >>
/var/log/ac
pi_events
rm /tmp/lidclose
else
echo "[" `date` "] Go to standby (lid closed)"
>> /var/log/acpi_eve
nts
touch /tmp/lidclose
# USB Module
rmmod uhci_hcd
rmmod
ehci_hcd
/sbin/hwclock --systohc
echo
mem > /sys/power/state
/sbin/hwclock --hctosys
modprobe uhci_hcd
modprobe ehci_hcd
fi
_________________________________________________________________
10.6.
Suspend to RAM just doesn't work after everything I've tried; what now?
Help us debug the problem. Here are some steps to take:
Rebuild your kernel with support for as few devices as possible,
preferably
no usb, and no pcmcia unless your network is pcmcia and
you have network
after you resume.
Turn off optional
devices in your BIOS; my Dell laptop lets me turn off the
modem
and wireless devices.
Turn off the framebuffer device.
Boot as single user, turn on networking and sshd if your machine is
pingable
after resume, turn on syslogging, and try suspend/resume
from there.
Turn off networking for good measure and try that,
just to see if that has
an impact.
Make sure your BIOS
is the most recent possible.
Check your DSDT; see [171]DSDT
editing for instructions.
If you are running an old
distribution, in particular an old version of X,
update it/them.
If you are using proprietary drivers, make sure you are
using the
most recent version.
Try suspend from X as well; video drivers
don't live in the kernel except
for framebuffer drivers, and
the X drivers sometimes know how to
reinitialize recent video
cards.
Look also at Documentation/video/blot.txt for more
things you can try.
If you still can't resume, get what you
can from the logs and submit a bug
report.
_________________________________________________________________
11.
Suspend to disk
11.1. How do I suspend to disk?
11.1.1.
Suspend to disk methods
Note: Suspend to disk is entirely
independent of the ACPI subsystem. But
it's included in this
document because, hey, what the heck.
There are three
different patches around for suspend to disk. As of this
writing,
the kernel has a set of patches inline, which are called swsusp and
which in this document I will refer to as swsusp1. Software Suspend 2
is a
set of patches not yet merged into the kernel; Software
Suspend 3 is a
user-space implementation still in the works.
Pm-disk, which used to be yet
another fork from swsusp1, was
combined with swsusp1 in mid-2004.
_________________________________________________________________
11.1.2.
How do I use Suspend to disk 1?
Make sure you have a swap
partition, not a swap file, that it's on a
separate physical
partition, and that it's at least as big as your memory.
If your
swap partition is on an LVM partition, read the later part of this
section; if it's on raid, there is support also [FIXME].
Back
up your data before your first test. No joke! If you happen to have an
unsupported driver, bad things can happen.
Get a few
patches first: the data free patch at
[172] the pagedir patch at
[173] and the memory leak patch at
[174] These apply to 2.6.14-rc2
cleanly.
Now, build your kernel with
CONFIG_SOFTWARE_SUSPEND=y. According to gossip
on the Linux kernel
mailing list, CONFIG_PM_STD_PARTITION is going to be
removed
someday; the approved method of specifying the resume partition is
to pass it as an argument at boot time. For Grub users, this means
appending
the argument "resume=/dev/something" to your kernel
boot line, where
"/dev/something" should be replaced with the
full name of your swap
partition.
Boot into the new
kernel. If you are watching closely, or if you check
/var/log/messages, you'll see that the kernel attempts to resume from
your
swap partition even though there's nothing to resume from
(yet). This is
normal behavior; your kernel will do this every
time. If you see this
message: swsusp: Error -6 check for resume
file, it means that your swap is
not on a physical partition or
that you have underlying modules that need to
be loaded before the
partition can be found. Check that IDE and/or SCSI
support is
built in directly to the kernel, and try again until this message
goes away.
For the first test, you might want to be root and
init 3 so that X isn't
running. It's also a good idea to unload
usb modules, PCMCIA modules, and
network/wireless modules.
Now give the following command: echo shutdown > /sys/power/disk;
echo disk >
/sys/power/state You will see all devices suspend
and then resume again
briefly; at this point the swap image will
get written and you'll see a
progress count. After the image is
written, devices will be suspended again
and then your system
should power off.
If you have mice or removable devices or
other hardware attached to your
system, LEAVE THEM ALL AS IS.
Don't change the hardware configuration at
all; resume expects to
resume to a system that is identical to the one it
suspended to.
Forbidden hardware configuration changes include plugging the
the
laptop when it was unplugged!
Press the power button briefly,
and you will go through the normal boot
sequence. Choose the same
kernel from the boot menu, with exactly the same
kernel arguments
you gave before; if you change this, you could lose all of
your
data.
Once you boot, the system should resume from the image
it wrote out earlier,
and you'll be returned to the exact state
you were in before suspension.
One thing that you may do,
without disturbing the resume process at all, is
to boot into a
different OS, as long as you don't touch the swap partition
or the
other partitions that were mounted when you did the suspend. You
cannot mount them from somewhere else, even if you don't touch anything
after the mount. So for example, you could boot into your 64-bit
version of
Linux on some other disk, do work there, then reboot
into the kernel from
which you suspended, using the same kernel
arguments as for the suspend, and
you'll be back where you were at
the point of suspension. Don't forget that
your hardware
configuration must not have changed!
On a system where your
swap partition is an LVM partition, you must take a
different
approach. You must use initrd/initramfs. It doesn't matter whether
your distribution supports the old initrd format or the new cpio format
(initramfs); in either case you make the same changes, but for the old
format you look at the file linuxrc in the image, and for the new
format you
look at the file init in the image, to add commands
that enable LVM.
Build your kernel with
CONFIG_SOFTWARE_SUSPEND=y. For
CONFIG_PM_STD_PARTITION, set
the value to "". DO NOT pass any resume=
argument to the kernel at
boot time or in your grub.conf. At suspend time,
this will cause
the kernel to look for the first swap partition it can see
and use
it to write the memory image. It will also cause the kernel to write
this message to /var/log/messages: resume= option should be used to set
suspend device. Ignore that error.
Now you must get several
supporting utilities or patches to them. [FIXME
other distros...]
For RedHat/Fedora, you need mkinitrd version 4.2.22-1 or later;
utils-linux
2.13-0.3.pre2 or later (for updated swapon); and
e2fsprogs 1.38-1 or later.
You can either build these from source
or get the binary rpms and install
them. At this writing, these
updates are only available from the rawhide
(unstable) release
tree, and installing the binary rpms requires
installation of
glibc*2.3.90-12 or later.
If you are using RH/Fedora, you can
use mkinitrd to create an initrd that
will support lvm and resume
from your swap partition. Just run mkinitrd
--allow-missing -f
/boot/initrd-2.6.14-rc3.img 2.6.14-rc3, substituting the
actual
name of your kernel for 2.6.14-rc3, such as 2.6.13-1.1588_FC5 or
whatever uname -r shows you. Mkinitrd will look for the first enabled
swap
partition and write the commands to make it available and
resume from it
into the init file in the new initrd.
If
you are using another distribution which includes mkinitrd, you should
check to see whether they have an updated version which supports lvm
and
resume from swap on a logical volume. You must use the new
mkinitrd to build
an initrd image that will be used when you
suspend/resume.
If you don't want to use your distribution's
mkinitrd or your distribution
doesn't provide one, then you can
build one yourself. At a minimum, it
should have a statically
linked version of /bin/lvm. Your init or linuxrc
script
should create /dev/mapper/control, run lvm vgscan
--ignorelockingfailure, run lvm vgchange -ay --ignorelockingfailure
VolGroup00 (you should include the volume groups that contain your
rootfs
and your swap partition), find the major and minor numbers
of your swap
partition, and echo them into /sys/power/resume. For
example, if your swap
were on /dev/mapper/VolGroup00-LogVol01
which showed
brw-rw---- 1 root disk 253, 1 Oct 2 03:31
/dev/mapper/VolGroup00-Lo
gVol01
then you would echo 253:1
> /sys/power/resume. All of this must be done
before any
filesystems are mounted. If you wait until afterwards, you are
almost guaranteed to have data corruption. It should also have a
fallback
present in case the resume fails (i.e. the next line
after the echo into
/sys/power/resume should handle resume
failure). [FIXME provide something
here that's more useful!]
Once you've got your initrd in place, make sure you edit your grub.conf
or
other boot configuration file to use the new initrd image
file: add a line
initrd /initrd-2.6.14-rc3.img (or whatever your
kernel name is) to the
stanza for booting your new kernel.
Example:
title Testing (2.6.14-rc3)
root
(hd0,2)
kernel /vmlinuz-2.6.14-rc3 ro
root=/dev/VolGroup00/LogVol00 rhgb quie
t
initrd
/initrd-2.6.14-rc3.img
To suspend, issue the following
command, just as in the discussion above for
non-initrd-based
suspend: echo shutdown > /sys/power/disk; echo disk >
/sys/power/state and observe the same caveats; no hardware changes,
don't
touch any partition that was mounted when you suspended,
don't touch the
swap partition.
When you press the power
button to resume, the init or linuxrc script in
your initrd will
start up LVM for you, check for the suspend image on your
swap
partition, and resume from it. For those who want to know more than
they should, the resume works by writing the device name as major:minor
device numbers into /sys/power/resume, which causes the kernel to try
to
resume from the swap on that device. (It bypasses the normal
kernel resume
path which would use the swap partition name
-- something like
/dev/mapper/VolGroup00-LogVol01 -- to try to
find an underlying physical
partition and would fail to find it
and fail to resume.) This leads to one
last caveat: never write
into /sys/power/resume yourself, or you will cause
the kernel to
try to resume from whatever device you specify, right then and
there. That is a sure recipe for disaster!
Using Nvidia
drivers with swsusp1 is easy. This document describes the
procedure for driver release 7676. Unpack the driver, edit nv.c to
change
this stanza:
case PM_SUSPEND_MEM:
nv_printf(NV_DBG_ERRORS, "NVRM: ACPI: received suspend event\n");
status = rm_power_management(nv, 0, NV_PM_ACPI_STANDBY);
break;
to read
case PM_SUSPEND_MEM:
case PM_SUSPEND_STANDBY: /* HACK */
nv_printf(NV_DBG_ERRORS, "NVRM: ACPI: received suspend event\n");
status = rm_power_management(nv, 0, NV_PM_ACPI_STANDBY);
break;
Rebuild your module and you're ready to go. If you are
using the intel_agp
module, you may need to use the
Option
"NvAgp" "0"
line in the "Device" section of your X
configuration file; other than that,
no special tweaks should be
needed. In some cases, your X display may come
back fine but
switching to other consoles may give you garbage; I find this
to
be true on my hardware.
[FIXME put info about ATI drivers
here, as needed.]
_________________________________________________________________
11.1.3.
Swsusp1 Resume failed; now what?
If resume fails after a
successful suspend, you have a suspend image written
to your swap
and you'll have to deal with it.
Add the boot parameter
"noresume" to your kernel boot arguments, boot up,
and this will
cause the kernel to boot normally. If you have the modified
swapon, then your swap partition will automatically be set be usable for
swap again. If you don't, you'll need to make the partition available
for
use as swap; do this by mkswap /dev/where-your-swap-is and
then swapon -a.
Now you are back to normal.
_________________________________________________________________
11.1.4.
How do I use Suspend to disk 2?
Note: the official name of
this code is "Software Suspend 2". In this
document, it is usually
referred to as swsusp2, even though that's not the
preferred
name. With three different suspend to disks floating around, it
helps me to keep them all straight.
Since Suspend to disk 2
has not been merged into the kernel, you'll have to
download the
patchset from [175] Version 2.2-rc8
has
been released for 2.6.14-rc3 and it applies cleanly. This document only
describes working with this version of the patchset. To apply the
patch,
unpack it, cd into the root of your kernel source
tree, and run
/path/to/patch-unpacked/apply
/path/to/patch-unpacked (the name of the
script is apply, and you
must tell it where the unpacked patch tree is).
You must also
download the hibernate script which goes with it, from the
same
place. Make sure the hibernate script version goes with the kernel
patches. Both rpms and tarballs are available. Assuming you retrieved
the
hibernate tarball, unpack it, change into the directory where
you unpacked
it, be root and then run ./install.sh. This puts the
scripts and config file
in appropriate places. You may want to
check /etc/hibernate/hibernate.conf,
and the list of modules
that hibernate will attempt to unload before
suspending, in
/etc/hibernate/blacklisted-modules. The defaults are usually
ok to
test with.
You can either use a swap partition or a file for
saving your suspend image.
Using a file will be covered in a later
version of this document. [FIXME]
Make sure you have a swap
partition that is at least twice as big as your
memory. If your
swap is on an LVM partition, read the later part of this
section;
if it's on raid, there is support also [FIXME].
Back up your
data before your first test. No joke! If you happen to have an
unsupported driver, bad things can happen.
Now, build your
kernel with CONFIG_SUSPEND2=y, CONFIG_SUSPEND2_SWAPWRITER=y,
CONFIG_SUSPEND2_CRYPTO=y, CONFIG_SUSPEND2_USERSPACE_UI=y, and
CONFIG_SUSPEND2_DEFAULT_RESUME2="". You should specify your resume
partition
by passing an argument at boot time. Of course, to avoid
typos, edit your
boot configuration. For Grub users, this means
appending the argument
"resume2=swap:/dev/something" to your
kernel boot line, where
"/dev/something" should be replaced
with the full name of your swap
partition.
If you want
to use compression, you should build LZF capability into the
kernel, by setting CONFIG_CRYPTO=y and CONFIG_CRYPTO_LZF=y. You can make
them into modules but then you must use an initrd image to supply these
modules at boot time.
Boot into the new kernel. If you are
watching closely, or if you check
/var/log/messages, you'll see
that the kernel attempts to resume from your
swap partition even
though there's nothing to resume from (yet). This is
normal
behavior; your kernel will do this every time. If you see this
message: Can't translate "/dev/..." into a device id yet., it means that
your swap is not on a physical partition or that you have underlying
modules
that need to be loaded before the partition can be found.
Check that IDE
and/or SCSI support is built in directly to the
kernel, and try again until
this message goes away.
For
the first test, you might want to be root and init 3 so that X isn't
running. It's also a good idea to unload usb modules, PCMCIA modules,
and
network/wireless modules.
Now give the following
command: /usr/local/sbin/hibernate You will see all
devices
suspend and then resume again briefly; at this point the swap image
will get written and you'll see a progress count. After the image is
written, devices will be suspended again and then your system should
power
off. It's really fast, much faster (in my experience) than
swsusp1.
If you have mice or removable devices or other
hardware attached to your
system, LEAVE THEM ALL AS IS. Don't
change the hardware configuration at
all; resume expects to resume
to a system that is identical to the one it
suspended to.
Forbidden hardware configuration changes include plugging the
the
laptop when it was unplugged!
Press the power button briefly,
and you will go through the normal boot
sequence. Choose the same
kernel from the boot menu, with exactly the same
kernel arguments
you gave before; if you change this, you could lose all of
your
data.
Once you boot, the system should resume from the image
it wrote out earlier,
and you'll be returned to the exact state
you were in before suspension.
One thing that you may do,
without disturbing the resume process at all, is
to boot into a
different OS, as long as you don't touch the swap partition
or the
other partitions that were mounted when you did the suspend. You
cannot mount them from somewhere else, even if you don't touch anything
after the mount. So for example, you could boot into your 64-bit
version of
Linux on some other disk, do work there, then reboot
into the kernel from
which you suspended, using the same kernel
arguments as for the suspend, and
you'll be back where you were at
the point of suspension. Don't forget that
your hardware
configuration must not have changed!
Many other useful entries
for swsusp2 are available under /proc/suspend2/.
Warning: please
note that this location is only valid for swsusp2 versions
2.2-rc8
and later! For earlier versions, you must look in the directory
/proc/software_suspend/ instead.
On a system where your swap
partition is an LVM partition, you must take a
different approach.
You must use initrd/initramfs.
Build your kernel with the
same configuration options as before.
Now you must get several
supporting utilities or patches to them. [FIXME
other distros...]
For RedHat/Fedora, you need mkinitrd version 4.2.22-1 or later;
utils-linux
2.13-0.3.pre2 or later (for updated swapon); and
e2fsprogs 1.38-1 or later.
You can either build these from source
or get the binary rpms and install
them. At this writing, these
updates are only available from the rawhide
(unstable) release
tree, and installing the binary rpms requires
installation of
glibc*2.3.90-12 or later.
If you are using RH/Fedora, you can
use mkinitrd to create an initrd that
will support lvm and resume
from your swap partition, with some hacking.
Change the line
echo "resume $swsuspdev" >> $RCFILE
to
echo "echo
> /proc/suspend2/do_resume" >> $RCFILE
. Warning:
please note that this location is only valid for swsusp2 versions
2.2-rc8 and later! For earlier versions, you must use the file
/proc/software_suspend/do_resume instead. Then you can run mkinitrd
--allow-missing -f /boot/initrd-2.6.14-rc3.img 2.6.14-rc3, substituting
the
actual name of your kernel for 2.6.14-rc3, such as
2.6.13-1.1588_FC5 or
whatever uname -r shows you. Mkinitrd will
look for the first enabled swap
partition and write the commands
to make it available and resume from it
into the init file in the
new initrd.
If you are using another distribution which
includes mkinitrd, you should
check to see whether they have an
updated version which supports lvm and
resume from swap on a
logical volume. You must use the new mkinitrd to build
an initrd
image that will be used when you suspend/resume.
It doesn't
matter whether your distribution supports the old initrd format
or the new cpio format (initramfs); in either case you make the same
changes, but for the old format you look at the file linuxrc in the
image,
and for the new format you look at the file init in the
image, to add
commands that do the resume.
If you don't
want to use your distribution's mkinitrd or your distribution
doesn't provide one, then you can build one yourself. At a minimum, it
should have a statically linked version of /bin/lvm. Your init or
linuxrc
script should create /dev/mapper/control, run
lvm vgscan
--ignorelockingfailure, run lvm vgchange -ay
--ignorelockingfailure
VolGroup00 (you should include the volume
groups that contain your rootfs
and your swap partition), and echo
*gt; /proc/suspend2/do_resume. All of
this must be done before
any filesystems are mounted. If you wait until
afterwards, you are
almost guaranteed to have data corruption. It should
also have a
fallback present in case the resume fails (i.e. the next line
after the echo into /proc/suspend2/do_resume should handle resume
failure).
[FIXME provide something here that's more useful!]
Once you've got your initrd in place, make sure you edit your grub.conf
or
other boot configuration file to use the new initrd image
file: add a line
initrd /initrd-2.6.14-rc3.img (or whatever your
kernel name is) to the
stanza for booting your new kernel.
Example:
title Testing (2.6.14-rc3)
root
(hd0,2)
kernel /vmlinuz-2.6.14-rc3 ro
root=/dev/VolGroup00/LogVol00 rhgb quie
t
resume2=swap:/dev/mapper/VolGroup00-LogVol01
initrd
/initrd-2.6.14-rc3.img
To suspend, issue the following
command, just as in the discussion above for
non-initrd/initramfs-based suspend: /usr/local/sbin/hibernate and
observe
the same caveats; no hardware changes, don't touch any
partition that was
mounted when you suspended, don't touch the
swap partition.
When you press the power button to resume, the
init or linuxrc script in
your initrd will start up LVM for you,
check for the suspend image on your
swap partition, and resume
from it. And if you haven't realized it yet,
never write into
/proc/suspend2/do_resume yourself, or you will cause the
kernel to
try to resume from whatever device you specify, right then and
there. That is a sure recipe for disaster!
Using Nvidia
drivers with swsusp2 may take a little work. You'll have to
rebuild your nvidia module as described above for swsusp1, and install
it.
Change any settings in your xorg.conf file as well, as
described above.
Then try the suspend. If it doesn't work,
what may happen is that you see
some disk activity, the screen
goes blank, there's more disk activity, and
then the machine stays
on. If this happens to you, see if Ctl-Alt-Delete
will let you
reboot your machine. If it does, then check your logs to see if
there is a complaint like "Pageset1 has grown by 381 pages. Only 100
growth
is allowed for!". If there is, you can (probably) change
one line and get
swsusp2 to run.
If in your log you
instead see a lot of lines like
scheduling while atomic:
hibernate/0x00000002/3313
[]
dump_stack+0x17/0x20
[]
schedule+0x557/0x620
[]
io_schedule+0xe/0x20
[]
do_bio_wait+0x19/0x30
[]
wait_on_one_page+0x1a/0x30
[]
suspend_do_io+0x39/0x40
[]
suspend_bdev_page_io+0x2f/0x40
[]
swapwriter_invalidate_image+0x5d/0x110
[]
suspend2_main+0xe0/0x1d0
[]
suspend2_write_proc+0xba/0x270
[]
proc_file_write+0x34/0x50
[]
vfs_write+0xb1/0x170
[] sys_write+0x3d/0x70
[] syscall_call+0x7/0xb
there may be so many
of them that they overflow the message buffer and you
don't see
all the steps for suspend/resume logged. To turn these off for the
moment, you'll need to edit kernel/sched.c, and in the schedule()
function,
edit this bit:
if
(likely(!current->exit_state)) {
if
(unlikely(in_atomic())) {
printk(KERN_ERR
"scheduling while atomic: "
"%s/0x%08x/%d\n",
current->comm,
preempt_count(), current->pid)
;
dump_stack();
}
}
to comment out
the
printk()
and the
dump_stack()
lines. Then run the suspend again; you should be able to see the real
suspend/resume errors and check what's wrong. When you are done,
uncomment
these lines and rebuild your kernel again, because these
catch other errors
than those just in swsusp2.
In your
linux kernel source tree with the suspend2 patches applied, edit
kernel/power/prepare_image.h: and change the line
#define
EXTRA_PD1_PAGES_ALLOWANCE 100
to read
prepare_image.h:#define EXTRA_PD1_PAGES_ALLOWANCE 500
. This
assumes that the pageset1 growth is < 500 pages. If it's much more
than that, this may be a sign of some other problem.
In some
cases, your X display may come back fine but switching to other
consoles may give you garbage; I find this to be true on my hardware.
[FIXME put info about ATI drivers here, as needed.]
Note: If
you are using Fedora Core 3 or 4, Matthias Hensler maintains kernel
rpms and special versions of mkinitrd at
[176]
which you can use. Rpms for the
hibernate script are also available for
download there.
_________________________________________________________________