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 here.
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, 2.6.0-test9, 2.6.0-test10 or 2.6.0-test11. 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
cd iasl-linux-20030918
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 ACPI-HOWTO.
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 dep
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:
cpi_status
acpi_os_table_override (struct acpi_table_header *existing_table,
                        struct acpi_table_header **new_table)
{
        if (!existing_table || !new_table)
                return AE_BAD_PARAMETER;

        *new_table = NULL;
        return AE_OK;
}
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;
That's it.
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

Disclaimer/Warranty/Other Stuff

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: zweitausenddrei_at_t-online.de.
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