Up until recently, I was the maintainer for the FreeBSD ACPI implementation. ACPI is a standard for making features like power management, which were originally in the BIOS, available to the OS to enumerate and control. I implemented the FreeBSD CPU frequency control framework and drivers for individual CPUs, as well as numerous bugfixes and updates to support new BIOS versions. I wanted to share my perspective on ACPI, as well as provide resources for other open source developers interested in getting involved in this obtuse area of PCs.
ACPI is a complex, 600-page standard. It assumes the reader has a lot of low-level knowledge about PC hardware and the BIOS. In the past, the BIOS would be the first thing that started on the PC. First, it would configure peripherals like PCI slots and boards. To retain control, it would hook the system management interrupt (SMI) before booting the OS. The SMI was tied to the actual hardware by the OEM, say by linking a laptop’s lid switch to a microcontroller. The BIOS had hard-coded event types and logic to process them (“if lid switch pressed, turn off backlight”). The nice thing was that the OS was completely unaware of the BIOS since the SMI is mostly invisible to software, so it could run on all PCs without changes. The downside was that the user had to go into the BIOS settings to change things and the BIOS had to be relatively complex in order to coexist with the OS.
In the ACPI model, the BIOS (or EFI now) still performs basic initialization. After the hardware is setup, it hooks the SMI. The difference is that it now provides a set of tables in RAM for the OS to consume. While most of the static tables describe the hardware, the most important one (“DSDT”) provides bytecode called AML. The OS sets up its interpreter very early in boot process and loads the BIOS’s AML. The AML is composed of methods and data types and is arranged in a tree that matches the logical arrangement of devices. For example, methods related to a video device would be located under the AML Device object for its parent PCI host interface.
The OS walks the AML tree, initializing the various devices and assigning resources to them using AML and device-specific methods. Usually, the OS keeps a mapping between its internal device driver tree and the handle to the AML node that shadows it. This allows it to later call methods under that node that change the power level or configure its wake capabilities. For example, you want the OS to power down an internal modem if it’s not in use. This is done by calling AML methods for the Device node that represents the modem.
The OS interoperates with ACPI this way constantly. The OS calls into AML (or vice versa via an interrupt) to power up/down devices, change backlight settings, change CPU frequency/voltage, or suspend/resume the system. While this level of control is nice to have as an OS developer, there have been a lot of bumps along the way.
ACPI could be seen as an attempt by Microsoft and Intel to take control over areas formerly owned by Phoenix/AMI and the numerous Taiwan integrators that actually build systems for companies like Dell. They had arguably good reasons for doing so, including the support cost of working around so many BIOS bugs. The conspiracy theorists may think that this was an attempt by Bill Gates to undermine Linux, but the pain that ACPI caused has been also borne by Microsoft. Gates never really got his proprietary extensions to ACPI, but Windows did enjoy a privileged position of OEMs using it as the validation suite for their BIOS implementations. Because there was no open interoperability testing, the spec was so complex, and information about the low-level BIOS and hardware were tied up in NDAs, open source kernels suffered many compatibility problems as new PCs appeared. The process definitely should have been more open and seems to be getting better, largely due to the efforts of Intel with Linux.
If you’re interested in learning more about ACPI, I recommend the following resources. The papers and talks are the best introduction, and I haven’t read the book yet. I hope this helps the open-source community improve support for ACPI.
Papers and talks
- Intro to FreeBSD ACPI (Takanori Watanabe, 2002)
- FreeBSD ACPI for developers: part 1 and part 2 (Nate Lawson, 2006)
- Intro to Linux ACPI (Len Brown, 2004)
- Linux ACPI update (Len Brown, 2005)
- ACPI in Linux (Max Berger, 1999, out-of-date)
- Intel ACPI book (2001, may be old)
Specs
- ACPI main spec
- Intel processor-specific adjunct
- Intel ACPICA open-source implementation