Author: Manolis Tzanidakis
The most important change since the last article is that laptops with multi-core CPUs are now the de facto standard. Intel Core Duo and Core2 Duo processors not only offer Symmetric Multiprocessing (SMP) functionality to mobile users but also consume less power, and thus produce less heat, than their predecessors.
These new multi-core CPUs are supported by the Linux kernel, but you need a fairly recent version to fully utilize them in SMP mode. Suspend-to-RAM with SMP enabled works in kernel versions 2.6.18 onwards, but it’s not 100% stable with occasional crashes on resume. Another problem I faced on a Core Duo system is the occasional miscalculation of the remaining battery life; the battery level might be at 70% one minute and then at 40% the next, and then back to 70%. However, things are greatly improved in kernel version 2.6.20 — marked as release candidate now — and if you own a multi-core laptop you should upgrade your kernel.
In the last article I mentioned the three available solutions for hibernating your system: swsusp (part of the kernel), uswsusp (an implementation of swsusp running in user space mode), and suspend2. I used the latter since it was the most stable and reliable method at the time. Suspend2 is a great piece of software, but it’s not part of the Linux kernel, so it requires manual patching and kernel compilation.
The good news is that uswsusp is now stable, well integrated with kernel versions 2.6.17 onwards, and supported by most major Linux distributions. Debian (Etch and Sid) and Ubuntu (Edgy Eft and Feisty Fawn) users can install the uswusp package, enter their swap space partition when asked by the package manager, and then run s2disk
to hibernate their laptop, as long as they run the stock kernel provided by their distribution.
Suspend script revisited and automation
Some readers suggested that the script I wrote for the previous article should store the system time to the hardware clock during suspend and then restore it from the hardware on resume to avoid clock skew problems. Actually, I use OpenNTPD on my systems to synchronize the clock over the network, so I’ve never faced such problems. Nevertheless it’s a nice suggestion. Another reader with better knowledge of sed than me offered a way to discover the PCI ID of the video card using a single sed command instead of the combination of grep, awk, and sed I used; writing elegant shell scripts is a form of art, so this goes in the new version of the suspend script too.
I’ve also added the option to suspend or hibernate based on a given argument; you can now run suspend.sh suspend
for suspend-to-RAM and suspend.sh hibernate
for hibernation.
Here is the new and improved suspend script. Paste it as /usr/local/sbin/suspend.sh and make it executable with chmod +x /usr/local/sbin/suspend.sh
.
#!/bin/sh # discover video card's ID ID=`lspci | sed -e '/VGA/!d' -e 's/ .*//' -e 's@0000:@@' -e 's@:@/@' -eq` # securely create a temporary file TMP_FILE=`mktemp /var/tmp/video_state.XXXXXX` trap 'rm -f $TMP_FILE' 0 1 15 # switch to virtual terminal 1 to avoid graphics # corruption in X chvt 1 # synchronize system clock with hardware hwclock --directisa --localtime --systohc # write all unwritten data (just in case) sync # dump current data from the video card to the # temporary file cat /proc/bus/pci/$ID > $TMP_FILE # suspend or hibernate case "$1" in suspend) echo -n mem > /sys/power/state ;; hibernate) s2disk ;; esac # restore video card data from the temporary file # on resume cat $TMP_FILE > /proc/bus/pci/$ID # synchronize hardware clock with system hwclock --directisa --localtime --hctosys # switch back to virtual terminal 7 (running X) chvt 7 # remove temporary file rm -f $TMP_FILE
I’ve tested this script on Debian Sid and Ubuntu Edgy Eft. Uswsusp offers the s2ram for suspending to RAM, but it didn’t work correctly during my tests, so I stuck to the trusted ACPI method.
If your laptop has a GeForce video card and you use the proprietary Nvidia drivers, you don’t need to store the video card data in a temporary file and restore it on resume, so remove those lines from the script. You need to follow some extra steps however. First of all, make sure to install the latest version of the 9xxx series of the Nvidia drivers (8xxx drivers don’t suspend correctly) and load the nvidia kernel module with the NVreg_Mobile=1
option. Also, in the device section in /etc/X11/xorg.conf, add this line: Option "NvAGP" "1"
.
At this point I need to apologize to owners of ATI Radeon-based laptops; since I don’t own one myself I can’t help you any further.
Now, let’s automate suspending or hibernating when closing the lid based on whether the AC adapter is present or not using acpid; i.e. suspend when the AC adapter is connected and hibernate when not. First create the /etc/acpi/events/lid file based on the instruction on the previous article, then paste the following as /etc/acpi/actions/lid.sh and make that file executable.
#!/bin/sh if grep -q off-line /proc/acpi/ac_adapter/AC/state; then /usr/local/sbin/suspend.sh hibernate else /usr/local/sbin/suspend.sh suspend fi
Note that on your laptop the AC adapter might be called something different in the /proc file system, so adjust the script accordingly.
To automate things even further we’ll have acpid hibernate the laptop automatically when the battery percentage level reaches 4%. Create the following files for handling battery events and actions:
/etc/acpi/events/battery
event=battery.* action=/etc/acpi/actions/battery.sh
/etc/acpi/actions/battery.sh
#!/bin/sh if grep -q on-line /proc/acpi/ac_adapter/AC/state; then exit 0 fi BAT_DIR=/proc/acpi/battery/BAT0 FULL_BAT=`grep 'last full capacity' ${BAT_DIR}/info | awk '{ print $4 }'` CUR_BAT=`grep 'remaining capacity' ${BAT_DIR}/state | awk '{ print $3 }'` AVG=`expr $(expr ${CUR_BAT} * 100) / ${FULL_BAT}` if [ "$AVG" -le "4" ]; then /usr/local/sbin/suspend.sh hibernate fi
Again, adjust the value of BAT_DIR to match your setup and make the second file executable with chmod +x /etc/acpi/actions/battery.sh
. Start the acpid daemon and you’re done.
Conclusion
Some readers might argue that this article is useless, since the last version of their favorite distribution does all these things automatically on their laptop. Sure, things have improved, but still they’re not perfect; for example, Ubuntu Edgy Eft still doesn’t resume my IBM ThinkPad R50e and Sony VAIO VGN-FE21M out of the box. However, distribution and kernel developers are not the ones to blame; the ACPI specification is largely misused by manufacturers. This article along, with sites such as TuxMobil and Linux on Laptops, could be useful for successfully running Linux on your laptop.