![]() ![]() | ||
- Linux On Mobile Computers - -> Linux Mobile Guide |
Start by reading the Battery-Powered-mini-HOWTO. For APM to work the machine's firmware must implement the APM Specification. Linux supports versions 1.0 through 1.2 of the standard. To work with Linux the APM BIOS must support 32-bit protected mode connections. To display information about the APM BIOS on your system you can run dmesg | grep apm command or look in the /proc/apm file. APM support consists of two parts: kernel support and user-land support. You need a kernel that has the APM driver compiled in using the appropriate kernel configuration options. Currently most distributions do not ship kernels with the APM driver enabled so you may have to enable the driver using a boot option or to compile a custom kernel. Please see Kernel-HOWTO or your distribution manual for details. The APM driver can be modularized but this is not recommended since many drivers will disable their APM features if the APM driver is not present when they initialize themselves. The available APM options are (please see Documentation/Configure.help in the kernel source tree for more details):
Features of the APM driver according to the Kernel documentation file Documentation/Configure.help: "The system time will be reset after a USER RESUME operation, the /proc/apm device will provide battery status information, and user-space programs will receive notification of APM events (e.g., battery status change). " The most important userland utility is apmd, a daemon that handles APM events. If you run a 2.2.x or later kernel and want to experiment, Gabor Kuti <seasons_AT_falcon.sch.bme.hu> has made a kernel patch that allows you to hibernate any Linux system to disk, even if your computers APM BIOS doesn't support it directly. In my humble opinion you don't need this features if your laptop provides a function key to invoke suspend mode directly. Please see the Battery Powered Linux Mini-HOWTO by Hanno Mueller by <kontakt_AT_hanno.de> and the page of Kenneth E. Harker for detailed information. Here's what apmd can do:
Some APM firmware fails to restore mixer settings properly which can result in squeals of feedback after music after the machine resumes. A solution is to set up the proxy script so that it calls a mixer application after resume. From the apmsleep(1) man page: Some computers, especially laptops, can wake up from a low-power suspend to DRAM mode using the Real-time clock (RTC) chip. Apmsleep can be used to set the alarm time in the RTC and to go into suspend or standby mode. An interrupt from the RTC causes the computer to wake-up. The program detects this event, by waiting for a leap in the kernel time and terminates successfully. If no time leap occurs within one minute, or something goes wrong, the exit value will be non-zero. Apmsleep is part of the apmd package. In 2001 Richard Gooch wrote a simple apmd alternative which is available in the pmutils package. Also, take a look at apmcd (apm based crontab) at ftp://ftp.binary9.net/pub/linux/ . This tool was written by Nicolas J. Leon <nicholas_AT_binary9.net>. If you use another operating system at the same computer make sure that its "suspend" and "hibernate" features don't write to partitions that are used by Linux. If your machine worked with 2.0.x kernels but not with the 2.2.x series, take this advice from Klaus Franken kfr_AT_klaus.franken.de : "The default changed in 2.2. Search in the init-scripts for halt and change it to halt -p or poweroff. See man halt , if you don't have this option you need a newer version of halt." You may find it in the SysVinit package. On some new machines (for instance HP Omnibook 4150 - 366 MHz model) when accessing /proc/apm, you may get a kernel fault general protection fault: f000. Stephen Rothwell explaines: "This is your APM BIOS attempting to use a real mode segment while in protected mode, i.e. it is a bug in your BIOS. .. We have seen a few of these recently, except all the others are in the power off code in the BIOS where we can work around it by returning to real mode before attempting to power off. Here we cannot do this." According to Kernel docs Documentation/Configure.help: "Some other things you should try when experiencing seemingly random, weird problems:
From the PCMCIA-HOWTO: "Card Services can be compiled with support for APM (Advanced Power Management) if you've configured your kernel with APM support. ... The PCMCIA modules will automatically be configured for APM if a compatible version is detected on your system. Whether or not APM is configured, you can use cardctl suspend before suspending your laptop, and cardctl resume after resuming, to cleanly shut down and restart your PCMCIA cards. This will not work with a modem that is in use, because the serial driver isn't able to save and restore the modem operating parameters. APM seems to be unstable on some systems. If you experience trouble with APM and PCMCIA on your system, try to narrow down the problem to one package or the other before reporting a bug. Some drivers, notably the PCMCIA SCSI drivers, cannot recover from a suspend/resume cycle. When using a PCMCIA SCSI card, always use cardctl eject prior to suspending the system.". Some machines have APM firmware that fails to save and restore display controller chip registers across a suspend. Earlier versions of the XFree86 X server did not restore the screen properly after resume, a problem which was addressed by Linux Laptops. However, contemporary versions of XFree86 mostly to the right thing. Sometimes X and APM don't work smoothly together. The machine might even hang. A recommendation from Steve Rader: Some linux systems have their X11 server hang when doing apm -s. Folks with this affliction might want switch to the console virtual terminal then suspend chvt 1; apm -s as root, or, more appropiately sudo chvt 1; sudo apm -s. I have these commands in a script, say, my-suspend and then do xapmload --click-command my-suspend . Software suspend enables the possibility of suspending a machine. It doesn't need APM. You may suspend your machine by either pressing Sysrq-d or with swsusp or shutdown -z (patch for sysvinit needed). It creates an image which is saved in your active swaps. By the next booting the kernel detects the saved image, restores the memory from it and then it continues to run as before you've suspended. If you don't want the previous state to continue use the noresume kernel option. Software suspends may even be better than hibernate, because now I can suspend my Linux system, boot into Microsoft Windows, perform a few illegal operations and be shut down, and then restart my Linux setup exactly where I left off! This is something that cannot be done with hibernation, since that always restores the last state that you suspended from, be it Microsoft Windows or Linux. So if I want to switch to Microsoft Windows to play games or do anything else, I can leave my Linux desktop exactly as it is and return to how I left it. In recent 2.5.x kernels SoftWareSuspend is part of the kernel. You may find it in the last section (Kernel Hacking). But there are also backports to 2.4 available. You may use the following entry in .bashrc to show the battery level on the command prompt.
# Color the bash prompt in function of the percentage of battery # with acpi subsystem. # Based on the originally apm based script that has been posted # on debian-laptop by # Jason Kraftcheck <kraftche at cae.wisc.edu>. # # This script is licensed under the GNU GPL version 2 or later, # see /usr/share/common-licences/GPL on a Debian system or # http://www.gnu.org/copyleft/gpl.html on the web. # (c) 2003 Fabio 'farnis' Sirna <farnis at libero dot it> function acpi_percent() { if [ `cat /proc/acpi/battery/BAT0/state | grep present: |cut -d\ -f18` = "yes" ]; then { CAPACITY=`cat /proc/acpi/battery/BAT0/info |grep "design capacity:"|cut -d\ -f11` LEVEL=`cat /proc/acpi/battery/BAT0/state | grep remaining|cut -d\ -f8` ACPI_PERCENT=`echo $(( $LEVEL * 100 / $CAPACITY ))` if [ "$LEVEL" = "$CAPACITY" ]; then echo FULL else echo $ACPI_PERCENT% fi } else echo "NO BATTERY" fi } function acpi_charge() { ACPI_CHARGE=`cat /proc/acpi/ac_adapter/AC/state | cut -d\ -f20` case $ACPI_CHARGE in *on-line*) ACPI_CHARGE="+" ;; *off-line*) ACPI_CHARGE="-" ;; esac echo $ACPI_CHARGE } function acpi_color() { if [ "$(acpi_charge)" = "+" ]; then { if [ `cat /proc/acpi/battery/BAT0/state | grep present: |cut -d\ -f18` = "no" ]; then echo "0;31" else echo "1;32" fi } else case $(acpi_percent) in 10?%) echo "0;32" ;; 9?%) echo "0;32" ;; 8?%) echo "0;32" ;; 7?%) echo "0;32" ;; 6?%) echo "0;32" ;; 5?%) echo "0;32" ;; 4?%) echo "0;33" ;; 3?%) echo "0;33" ;; 2?%) echo "0;33" ;; 1?%) echo "0;31" ;; ?%) echo "0;31;5" ;; *) echo "0;35" ;; esac fi } function acpi_color_prompt { PS1='\[\e[$(acpi_color)m\][$(acpi_charge)$(acpi_percent)][\t] \u:\w\$>\[\e[0;37m\] ' } # linux console if [ "$TERM" = "linux" ]; then PROMPT_COMMAND=acpi_color_prompt fi function echo_acpi { echo -n "($(acpi_charge)$(acpi_percent)) " }
All "normal" Debian GNU/Linux kernels are APM capable, they just need an append line added to the boot loader configuration file (e.g. /etc/lilo.conf. append="apm=on"
You might use the following parameters (with the appropriate changes) in your boot loader configuration file (e.g. /etc/lilo.conf to experiment with ACPI and APM, when compiled in the same kernel. Usage of APM and ACPI at the same time doesn't work, see Kernel docs for details. append="acpi=off apm=on"
|