acpi-apm V2.0a

What is this?

acpi-apm is a Linux kernel module that simulates the output from /proc/apm on systems that have ACPI, not APM, for power management. Why is this useful? A great deal of software uses /proc/apm to determine the power and battery status, including the Gnome and KDE applets that display battery status. Modern PCs, particularly laptops, are increasingly using ACPI for power management, and don't support APM very well. To use one of these systems you need to compile ACPI support into the kernel, and disable APM. You therefore lose /proc/apm. There are equivalent power monitoring utilities for ACPI, but they never seem to work very well. With this module, it appears to applications like Gnome that APM is available.
      Please note that acpi-apm  does not simulate the control features of APM, only the monitoring. You won't be able to use this module to give you a suspend-to-RAM feature if your kernel doesn't support it through ACPI. What's more, it does not provide an interface to /dev/apm_bios (not yet; maybe never). A small number of power monitoring utilities interact with apm_bios directly, so this module won't help them. Among that small number, annoyingly, is the standard `apm' utility supplied with most Linux utilities.
   acpi-apm
works by intercepting reads made on /proc/apm, determining the power status from ACPI, then simulating the APM values based on the ACPI values. You need to have ACPI support compiled into your kernel and working before using this module. If you already have APM support in your Linux kernel, you don't need this module, and it will not load.

What APM utilities does acpi-apm work with?

acpi-apm should work with any utility that reads /proc/apm. It works (which is to say, it has been reported to
work by at least one person) with xapm, battstat-applet (versions supplied with RedHat Linux from 7.2-9),
and power-applet v0.5.

What kernel versions does it work with?

V2.0a of this module is radically different from earlier versions. In particular, the method it uses to get access to the battery status from ACPI is extremely ugly, but ought to work with most modern kernels, and most versions of the ACPI patches that are currently in circulation.
     Previous versions attempted to get to the ACPI data through ACPI API calls embedded in the kernel. These calls are not well documented, and prone to change. As a result, I had to tweak the module for every trivial change in the ACPI patches. Then after kernel version 2.4.17 I couldn't get the previous version to work at all, with any amount of tweaking. This version works with 2.4.23, and ought to work with other kernels as well. If you find it compiles, but does not produce credible output from /proc/apm, please let me know.

Do I need to recompile the kernel to use acpi-apm?

No. No part of the kernel needs to be recompiled, and this module will not interfere with any other part of the kernel (as far as I know). However, you will need to have ACPI support working and, at the time of writing, no standard Linux distribution had ACPI support. So you would have had to recompile the kernel to get ACPI to work in the first place.

Compiling and installing

You will need to compile this. Please don't ask me for binaries, as it's too much hassle to generate them. Compiling should not be difficult, but you will need to have kernel headers installed, as well as the compiler itself. To compile, unpack the archive and run

% make


in the source directory.

If it doesn't compile, and you have all the prerequisites, e-mail me. The compilation should generate the file acpi-apm.o. Install the module by doing

# make install

 Load this module into the kernel by doing

# modprobe acpi-apm [jiffies_delay=NNNNN]

See below for a description of the jiffies_delay parameter. Run

% dmesg

and ensure there are no error messages from the module.

That's it. If you do a cat /proc/apm you should see some numbers in decimal and hex. If you get a segmentation fault, e-mail me. How you get the module loaded at boot time is up to you: rc script or whatever.


Configuration

This module takes one initialization parameter: jiffies_delay. This is minimum amount of time the module will allow between real access to the ACPI subsystem. If /proc/apm is read more frequently than that, then the reader will get the last value, which the module keeps in a cache. This is very important, because ACPI access is much, much slower than APM on Linux systems (perhaps on all systems). So utilities that were designed with APM in mind hammer the /proc/apm file ferociously. The Gnome battstat-applet, for example, reads several times per second. This frequency of access would bring most systems to a crashing halt. Of course, frequent polling of /proc/apm allows the display to update rapidly if, for example, the power cable comes uplugged. This is handy but, in most circumstances, updating a couple of times a minute should be enough. Since a `jiffy' is 1/100th of a second,  to load acpi-apm with a 30 second update time, do this:

# modprobe acpi-apm jiffies_delay=3000

Bugs and limitations

This module is extremely simply, and has its own limitations. There are also limitations with ACPI itself. You should bear in mind the following if the module does not work as expected

Technical notes

This module works by reading an parsing the contents of /proc/acpi/battery/BAT1/state and /proc/acpi/battery/BAT1/info. It takes the data from these files, does a bit of arithmetic, and generates a simulation of the contents of /proc/apm. acpi-apm does not read the files in the sense that an application program would read them; that is, it does not generate a system call into the kernel's VFS layer (we are in the kernel already). Instead it finds the location in the kernel's address space of the function that ultimately has to be invoked when these files are read, and calls that function directly. It finds the function by getting a struct file object for the file using filp_open, and navigating down to the read() function in the file_operations structure. I suppose that ideally the module should try to find a cached dentry for the files before doing filp_open(), but since all operations on /proc are done in memory, I don't think it would make much difference to the speed of response. The module allocates exactly one page of kernel memory, so if there ever comes a time when the files in /proc/acpi are more than 1 kB long, we'll be in trouble. I can't guarantee that there aren't error conditions that will cause a buffer to overflow in the module, and crash the machine. I've tried to trap most of the obvious problems, but the module does rely to a certain extent on the ACPI subsystem outputting meaningful data.

Author and legal

This kernel module was written by Kevin Boone and is (c)2002-2004. You may do whatever you like with the source code, provided that you continue to acknowledge the author in any distribution of it, and of any distribution of code substantially derived from it; and that you make the original source code available. Needless to say, there is no warranty of any kind, and you use this at your own risk. Please report bugs, etc., to kb@kevinboone.com.