random quote: "You can have my Unix system when you pry it from my cold, dead fingers."
Cal Keegan
|
|

ACPI sleep states :: using suspend-to-disk and suspend-to-ram on linux
ACPI sleep states enable you to send the system in a low-power consuming sleep mode. There are two sleep modes dealt with in this howto:
- ACPI S3, sleep mode 3, also referred to as suspend-to-ram. This is a state of very low power consumption, where most of the hardware is switched off, and only a little energy is used to keep the memory alive during sleep.
- ACPI S4, also referred to as suspend-to-disk. This is a state where no power is consumed. An image of the memory is written to disk, then the hardware is switched off. Booting the system will read the image back and restore all running programs.
Suspend-to-disk in contrast to suspend-to-ram doesn't consume any power while sleeping, but it is a bit slower than S3 with respect to suspend and resume time. As a reference, it takes my system about 25 seconds to suspend to disk, about 30 seconds to resume from suspend to disk. Suspending to RAM takes 6 seconds, resuming from S3 takes roughly 8 seconds.
In most cases, suspend-to-disk is easier to get working than suspend-to-ram. You should, however, have the necessary skills to patch, configure, compile and set up the linux kernel on your system. Depending on the hardware you have, the drivers and kernel features you use, it may - or may not - work. At the moment of writing, not all of the drivers in the linux kernel and devices support this kind of power management properly. The software suspend 2 wiki offers some information on which drivers are known to cause problems.
This Howto describes how you might get Software Suspend2 (S4) and ACPI Suspend-to-RAM (S3) to work on a Asus L3800C notebook under Linux. Most parts of the howto are not too hardware specific, so if you own another model, the below might also give you some hints on how to get the beast asleep (and properly wake it up!). By using the terms Software Suspend, suspend2 I refer to Nigel Cunningham's patches that provide a far more enhanced suspend-to-disk support for the linux kernel than the vanilla-swsusp-as-of-2.6.9. There are some differences setting these things up, so please don't get confused. :-)
This document is published under the terms of the GNU Publics License, v2 or later. Thanks to Bernard Blackham for reviewing. If you have questions or suggestions, please don't hesitate to contact me.
jump to: prerequisites kernel configuration software suspend 2 setup suspend-to-ram setup troubleshooting caveats more information
prerequisites.
I have the following relevant software installed on my system. I am using Debian Sid on the notebook, linux 2.6.9 with the desktop performance patchset from Con Kolivas.
The following versions might be interesting:
- linux probably at least 2.6.9
- patches for software suspend 2 applied (see the suspend2 howto)
- XFree 4.3 (4.3.0.dfsg.1-8 from apt), newer versions should also be OK or better
kernel configuration.
The following sections are relevant for proper working of the sleep states. Here's a link to a 'works for me' kernel .config.
ACPI:
$ zgrep ACPI /proc/config.gz
# Power management options (ACPI, APM)
# ACPI (Advanced Configuration and Power Interface) Support
CONFIG_ACPI=y
CONFIG_ACPI_BOOT=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_ASUS=y
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_BUS=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI=y
# CONFIG_SERIAL_8250_ACPI is not set
setting up software suspend 2
Software Suspend 2 requires a kernel patch, but it adds some nice features to suspend-to-disk. Using suspend2, you are able to compress the image that's written to disk, this is a major speed improvement above the in-kernel suspend-to-disk implementation (swsusp). Here's how to set up suspend2:
First, patch your kernel with the patches from the software suspend website. There's a script contained in the packages which helps you to apply the patches to the kernel source:
cd /usr/src/linux (the root directory of your tree)
/path/to/software-suspend-2.1-for-2.6.9/apply
The software suspend packages usually contain some options which you might not want to use (kdb / kernel debugger support or bootsplash). You can remove these patches from the software-suspend-2.1-for-2.6.9/ directory. Another way to apply the patches is
cd /usr/src/linux (the root directory of your tree)
cat /path/to/software-suspend-2.1-for-2.6.9/* |patch -p1
(Note that the --dry-run option for patch might announce failed hunks, while the patches actually apply cleanly due the nature of them being split up.)
For Software Suspend 2, I have set the following options:
# CONFIG_SOFTWARE_SUSPEND is not set ?-- this is the in-kernel suspend-to-disk!
CONFIG_SOFTWARE_SUSPEND2_CORE=y
CONFIG_SOFTWARE_SUSPEND2=y
CONFIG_SOFTWARE_SUSPEND2_WRITER=y
CONFIG_SOFTWARE_SUSPEND_SWAPWRITER=y
CONFIG_SOFTWARE_SUSPEND_LZF_COMPRESSION=y
# CONFIG_SOFTWARE_SUSPEND_GZIP_COMPRESSION is not set
CONFIG_SOFTWARE_SUSPEND_BOOTSPLASH=y
CONFIG_SOFTWARE_SUSPEND_TEXT_MODE=y
CONFIG_SOFTWARE_SUSPEND_DEFAULT_RESUME2="swap:/dev/hda2"
CONFIG_SOFTWARE_SUSPEND_DEBUG=y
With the RESUME2 option, you can specify a default location where to look for the suspend2 image. You can also specify this as a kernel parameter in your bootloader configuration (see below). I am using my swap partition to store the image. I selected LZF as compression algorithm, since it's amazingly fast. For most users, Switching on LZF and switching off GZIP compression is a good choice. While GZIP reaches a higher compression rate than LZF, it's much slower. Actually, in most cases using a gzipped compressed image is slower than using no compression, although far less data has to be stored in the suspend image. Using LZF, the data can be compressed fast enough to write with full speed to the hard disk. The swap partition should be big enough to store the image. It largely depends on the usage profile, but in most cases a swap partition of about the same size as the RAM is safe. Suspend 2 has features to control the size of the image,
# echo 400 > /proc/software_suspend/image_size_limit
makes suspend try to free some memory. (It's a soft limit.) In this case, an image of 400 MB will be compressed and written to disk (so you effectively have to write roughly 200MB to disk, depending on the compression rate with LZF, mine is usually between 40% and 60%). You can also use a swapfile to suspend to, in case you lack swap space. The details for doing this can be found in Documentation/power/suspend2.txt in the kernel sourcetree.
Prior to the kernel part of suspending and right afterwards, there is some help from userspace necessary, my small script (ignore the style ;-)) does that:
#!/bin/sh
# hibernate script for neo, 2.4.23, softwaresuspend 2.-rc3
# hibernate script for neo, 2.6.9-ck3, softwaresuspend 2.1.5
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/sbin
# MySQL is not suspendable
ps x|grep mysqld|grep -v grep >> /dev/null && /etc/init.d/mysql stop >> /dev/null 2>&1
# Having stale mounts when resuming with the network cable unplugged is not funny
umount -f /mnt/nfs-marvin > /dev/null 2>&1
# Unloading and reloading of uhci_hcd makes the USB mouse work after resume
rmmod uhci_hcd
date
echo -e "3[1;31mhibernating 3[0m"
# Switch bootsplash framebuffer to 'silent mode'
echo "silent" > /proc/splash
# Switch to bootsplash console
chvt 1
# Write dirty data to disk, to prevent data loss in cases of failure.
sync
# Go, sleep!
echo 4 > /proc/acpi/sleep
# or
# echo > /proc/software_suspend/do_suspend
echo -e "3[1;32m... back 3[0m"
# Switch back to X
chvt 7
modprobe uhci_hcd &
# Fix clock skew
hwclock --hctosys &
If you are looking for a more convenient way to control the various settings suspend2 offers, consider using the hibernate-script. It's already available in some distributions (Debian Sid, Gentoo Linux ~arch), it's modular, easily configurable and well-documented.
That said, I use my small script mainly for traditional reasons (that is: I'm too lazy to reconfigure that stuff or never change a winning team, choose two. :P).
setting up S3.
Actually, there's not too much to set up to use S3, you only have to figure out what. I suspect acpid to cause crashes sometimes, so I disabled it. I also stopped hotplug because USB has the reputation of being a little powermanagement-agnostic and I don't want to have drivers loaded automatically while the script runs. Also, I have minor glitches with acpi events (read also later on). After some trial and error (be careful with your filesystem!), the following small script made my notebook go to sleep and return working (it's not really clean, but you get the point):
#!/bin/bash
# suspend-to-ram : Sends the machine to S3,
# performing some tasks before and after wakeup.
PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/sbin
echo -e "3[1;31mInitiating suspend-to-ram 3[0m"
# Empty logfile
echo > /tmp/suspend.log
/etc/init.d/hotplug stop >>; /tmp/suspend.log 2>&1
/etc/init.d/acpid stop >> /tmp/suspend.log 2>&1
# Flush disk buffers, so we won't lose to much data in case it fails
sync
# Go, sleep!
echo 3 > /proc/acpi/sleep
echo -e "3[1;32m... back 3[0m"
# http://bugme.osdl.org/show_bug.cgi?id=3609
setpci -s 00:1f.0 f2.b=1
/etc/init.d/acpid start >> /tmp/suspend.log 2>&1 &
/etc/init.d/hotplug start >> /tmp/suspend.log 2>&1 &
It is probably a good idea to use the hibernate-script written by Bernard Blackham and others, it's suitable for both, software suspend and suspend-to-ram.
bootloader configuration.
I am using grub as my bootloader. I had to append acpi_sleep=s3_bios to the kernel parameters, otherwise my display would stay black after resuming from S3. Note that the acpi_sleep= parameter might vary, depending on the kind of hardware used. Here's the entry from my /boot/grub/menu.lst:
title Linux 2.6.9-ck3-suspend2
root (hd0,0)
kernel /boot/vmlinuz-2.6.9-ck3-suspend2 ro acpi_sleep=s3_bios \
resume2=swap:/dev/hda2 apm=off vga=0x317 \
video=vesa:ywrap,mtrr splash=silent
initrd /boot/initrd.current
savedefault
The video and splash parameter are for bootsplash, they are not necessary for S3 though. The same applies to the initrd. (I compiled in the options that save me having to create an initrd for every new kernel).
If you are having screen corruption issues, try to boot with vga=normal, switching of the framebuffer.
If you are using lilo, you'll have to add the acpi_sleep=s3_bios paramter to the 'append' line. For suspend2, the resume2=swap:/dev/hda2 is important. Change /dev/hda2 to reflect the location of your swap partition.
troubleshooting.
Obviously, not all processes can be suspended without problems (acpid, for example causes trouble here). Also, some drivers tend to cause problems, or simply don't work after sleep. Compiling these drivers or features as a module is usually a good idea, since you can then unload them prior to suspending as a workaround. You can troubleshoot these kinds of situations as follows:
- Boot a minimal system, for example with init=/bin/bash as kernel parameter and as little modules loaded as possible
- Try to suspend and resume the system
If that does work:
- Add drivers one by one to the system, checking if it works with the drivers loaded
- Add services one by one, try to find out which one causes problems
- If you have identified the troublemaker, disable the service prior to suspend and reenable it afterwards.
caveats.
Note that I am using a bootsplash framebuffer console. If you have problems with the screen garbled after resume, try vga=normal as parameter. Alhough Documentation/power/video.txt says that framebuffer consoles are likely to screw things up, it does seem to work for me (tm) using vesafb. Powermanagement support in framebuffer drivers is still a little flaky, so you might be lucky - or not. ;-) Documentation/power/video.txt from the linux kernel source has some clues, you should read that if you have problems with your video.
I also have problems with ACPI events from time to time. It might help if you disable ACPI wakeup events, this can be done as Nigel Cunningham described on the suspend2 mailinglist (notice the SLPB setting):
[...]
In the meantime,
looking at /proc/acpi/wakeup might help if it's a wake event. (cat it
and see what's enabled, then echo the four letter code at the start into
it to toggle that status of an entry...)
[root@desktop src]# cat /proc/acpi/wakeup
Device Sleep state Status
TANA 4 disabled
P0P3 4 disabled
AC97 4 disabled
USB0 3 disabled
USB1 3 disabled
USB2 3 disabled
USB3 3 disabled
USB7 3 disabled
UAR1 4 disabled
SLPB 4 *enabled
[root@desktop src]# echo SLPB > /proc/acpi/wakeup
[root@desktop src]# cat /proc/acpi/wakeup
Device Sleep state Status
TANA 4 disabled
P0P3 4 disabled
AC97 4 disabled
USB0 3 disabled
USB1 3 disabled
USB2 3 disabled
USB3 3 disabled
USB7 3 disabled
UAR1 4 disabled
SLPB 4 *disabled
[root@desktop src]#
DRI / direct rendering for X is supposed to work (and actually does!) with powermanagement right away in newer versions of XFree86 and Xorg. Hardware overlay (for mplayer for example) however, works fine after resuming. The binary video drivers provided by ATi and NVidia are known to cause problems. At least, NVidia is working on proper powermanagement support for their drivers. The OpenSource radeon and nv drivers work fine. I also had good experiences with Thomas Winischofers SiS video drivers.
USB power management support is still a little flaky, so this might also cause problems. Unloading the uhci_hcd module prior to suspend and reloading it afterwards might help. Also, other drivers (e.g. ohci_hcd) might work with this workaround.
Suspend2 might cause problems in conjunction with CONFIG_HIMEM. The patchset from Con Kolivas contains a patch to use 1 GB as LOWMEM, so if you have 1GB or RAM, you might be able to workaround with that patch.
This left me with a working** setup. However, having suspended to RAM a couple of times, trying to hibernate would cause my system to freeze. Karol Kozimor suggested a workaround for that. ACPI S3 messes up the PCI space somehow, that has to be reset after S3. The line
# setpci -s 00:1f.0 f2.b=1
does that. There is already a bug filed, so I expect it to be fixed in one of the upcoming kernel releases.
** I still suffer from crashes from time to time, but it seems to be getting usable, 2.6.10 seems to have also brought a couple of improvements
more information and more or less related links.
26-11-2004, 03:19 h © Sebastian Kügler
|