Using 2.4.22 or 2.6.0-test9/10/11 ACPI features with buggy dsdt.
I recently wanted to have a look at the battery state of my laptop (Samsung V20, 2.0 GHz version) using Linux, but some ugly error messages during boot appeared, telling me that acpi wont work.
The problem is that many bios manufacturers implement the acpi interface poorly (e.g. some functions return no value). In contrast to linux, windoze simply ignores this problem and acpi will work.
The main reason for me to write this guidance was not the poor information on the internet, but you have to fetch information from many different web pages, more or less complete. some ways to get acpi working did not work (I'm too stupid), some were for older kernels that i did not want to use and some for specific distributions... here is a description how to get acpi working with a buggy bios and relatively new kernels ;)
What you need to do to get your ACPI working
1. Use Ubuntu or Suse Linux. Both distributions support broken ACPI tables out of the box.
2. Your favourite Distribution:
You need the binary IASL-Compiler from Intel. Get it
You need access to /proc/acpi/dsdt. This means you need a kernel running with acpi support (which, of course is /nearly/ worthless at the moment ;).
This file is your bios dsdt table. If you dont have /proc/acpi/dsdt, then you either have no acpi or no acpi kernel-support.
In case of lacking kernel-acpi you can check out
pm-tools to get the dsdt file out of your bios.
It's also a good time now to download a new kernel from www.kernel.org,
this document describes changes needed for 2.4.22 and 2.6.0-test9, but
there should be no problem to use a newer kernel and apply the patches.
Then get the patch files either for 2.4.22,
Save the kernel and the patch in the same directory, then unpack the kernel using
tar -xzvf linux-2.x.xx.tgz or
tar -xvjf linux-2.x.xx.tar.bz2
and install the patch:
patch -p0 < 2.x.xx-dsdt.table.diff
If the patch fails or isn't available from here at the moment (what should not happen ;), read on below
/how to patch the kernel manually/.
Now its time to use iasl.
tar -xvzf iasl-linux-20030918.tar.gz
cp /proc/acpi/dsdt . (you need to be root to do this, then change user and group of this file or continue as root)
./iasl -d dsdt
will disassemble dsdt to dsdt.dsl.
Now you have to correct the dsdt.dsl file. Although it is some kind of assembler code, you dont need to know how to program in assembler ;)
try to assemble the dsdt.dsl file /without/ modifying it:
./iasl -tc dsdt.dsl
The Compiler will complain if you have a buggy bios. My output looks like this:
luser@mars ~/iasl-linux-20030918 $./iasl -tc dsdt.dsl
Intel ACPI Component Architecture
ASL Optimizing Compiler / AML Disassembler version 20030918 [Sep 18 2003]
Copyright (C) 2000 - 2003 Intel Corporation
Supports ACPI Specification Revision 2.0b
dsdt.dsl 3454: Field (ECR, DWordAcc, Lock, Preserve)
Error 1048 - ^ Host Operation Region requires ByteAcc access
dsdt.dsl 4720: Method (_WAK, 1, NotSerialized)
Warning 2026 - ^ Reserved method must return a value (_WAK)
ASL Input: dsdt.dsl - 4775 lines, 170013 bytes, 2450 keywords
Compilation complete. 1 Errors, 1 Warnings, 0 Remarks, 537 Optimizations
luser@mars ~/iasl-linux-20030918 $
Your output may and probably will vary.
If you get iasl to compile the code without complaining, _acpi_will_work_ :))
Now you have to take a look at this
Jump to section 'fix_broken_dsdt', there are possible compiler errors and
solutions how to fix them in you dsdt.dsl file.
The solutions there worked fine for my dsdt, I just followed the instructions.
After modifying dsdt.dsl, recompile again:
./iasl -tc dsdt.dsl
Hopefully the compiler won't complain again and you can move the beast into your kernel directory:
mv dsdt.hex /path/to/patched_linux/drivers/acpi/dsdt_table.h
now go to your updated linux directory, do
make menu/x/config (don't forget acpi support ;)
make bzImage && make modules && make modules_install
Then do lilo/grub configuration etc.
Congratulations! Your kernel has /useful/ acpi support now!
How to patch the Kernel manually
If something goes wrong during patching (newer kernels than supported on this page or something else) you can still patch your kernel manually. This is not a hard task, you just have to edit /linux/drivers/acpi/osl.c
Near the top of the file, add
#include "dsdt_table.h" above the other include files.
then search for this section:
acpi_os_table_override (struct acpi_table_header *existing_table,
struct acpi_table_header **new_table)
if (!existing_table || !new_table)
*new_table = NULL;
delete the following line:
*new_table = NULL and replace it with:
*new_table=(strncmp(existing_table->signature, DSDT_SIG, 4)) ? NULL
: (struct acpi_table_header *) AmlCode;
Note: Some patched distribution kernels (for example Mandrake) seem to omit the 'struct' statement before acpi_table_header*.
If you get compiler errors while compiling your new kernel, try to delete struct and it should work.
Some useful links related to Linux/ACPI
ACPI project page on sourceforge.net
ACPI-HOWTO mentioned above
Intel ACPI Homepage/FAQ
Loading dsdt - tables using initrd
I don't take any responsibility for damage caused by this patch, it's your system and you know what you are doing.
If you've managed to get acpi working send an angry email to your bios manufacturer and include the corrected dsdt.dsl and dsdt.hex files.
If you have any suggestions, comments or questions, don't hesitate to mail to:
Thanks go to: Biggi, Frédéric Parrenin, Georg Neis and all people who spent their time on open source software.
Page last modified: 05/13/2006